X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_triggers.pas;h=7c44d9839ebe3c9013fb0881850c9f979cc97e23;hb=6fdaf7454535407de0331bdc6b96e538919525a6;hp=064b3b6cebba673302668005eb580130f48e1789;hpb=b0369ee9442a79c9ace3454e7e1709cd61ed6a8e;p=d2df-sdl.git diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index 064b3b6..7c44d98 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -38,7 +38,7 @@ type Enabled: Boolean; ActivateType: Byte; Keys: Byte; - TexturePanel: Integer; + TexturePanelGUID: Integer; TexturePanelType: Word; TimeOut: Word; @@ -63,8 +63,8 @@ type ShotReloadTime: Integer; mapId: AnsiString; // trigger id, from map - //trigShotPanelId: Integer; - trigPanelId: Integer; + mapIndex: Integer; // index in fields['trigger'], used in save/load + trigPanelGUID: Integer; //TrigData: TTriggerData; trigData: TDynRecord; // triggerdata; owned by trigger @@ -73,10 +73,10 @@ type function trigCenter (): TDFPoint; inline; public - property trigShotPanelId: Integer read trigPanelId write trigPanelId; + property trigShotPanelGUID: Integer read trigPanelGUID write trigPanelGUID; end; -function g_Triggers_Create(Trigger: TTrigger): DWORD; +function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD; procedure g_Triggers_Update(); procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0); function g_Triggers_PressR(X, Y: Integer; Width, Height: Word; UID: Word; @@ -89,18 +89,6 @@ procedure g_Triggers_Free(); procedure g_Triggers_SaveState(var Mem: TBinMemoryWriter); procedure g_Triggers_LoadState(var Mem: TBinMemoryReader); -function tr_Message(MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean; - -function tr_CloseDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; -function tr_OpenDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; -procedure tr_CloseTrap(PanelID: Integer; NoSound: Boolean; d2d: Boolean); -function tr_SetLift(PanelID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean; - -function tr_Teleport(ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean; -function tr_Push(ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean; - -procedure tr_MakeEffect(X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean); -function tr_SpawnShot(ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer; var gTriggerClientID: Integer = 0; @@ -108,16 +96,18 @@ var gSecretsCount: Integer = 0; gMonstersSpawned: array of LongInt = nil; + implementation uses - g_player, g_map, Math, g_gfx, g_game, g_textures, + Math, + g_player, g_map, g_panel, g_gfx, g_game, g_textures, g_console, g_monsters, g_items, g_phys, g_weapons, wadreader, g_main, SysUtils, e_log, g_language, - g_options, g_net, g_netmsg, utils; + g_options, g_net, g_netmsg, utils, xparser; const - TRIGGER_SIGNATURE = $52475254; // 'TRGR' + TRIGGER_SIGNATURE = $58475254; // 'TRGX' TRAP_DAMAGE = 1000; @@ -127,109 +117,118 @@ begin end; -function FindTrigger(): DWORD; +function FindTrigger (): DWORD; var i: Integer; begin - if gTriggers <> nil then - for i := 0 to High(gTriggers) do - if gTriggers[i].TriggerType = TRIGGER_NONE then - begin - Result := i; - Exit; - end; + for i := 0 to High(gTriggers) do + begin + if gTriggers[i].TriggerType = TRIGGER_NONE then begin result := i; exit; end; + end; - if gTriggers = nil then + if (gTriggers = nil) then begin SetLength(gTriggers, 8); - Result := 0; + result := 0; end else begin - Result := High(gTriggers) + 1; - SetLength(gTriggers, Length(gTriggers) + 8); + result := Length(gTriggers); + SetLength(gTriggers, result+8); + for i := result to High(gTriggers) do gTriggers[i].TriggerType := TRIGGER_NONE; end; end; -function tr_CloseDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; + +function tr_CloseDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; var a, b, c: Integer; + pan: TPanel; + PanelID: Integer; begin - Result := False; - - if PanelID = -1 then Exit; + result := false; + pan := g_Map_PanelByGUID(PanelGUID); + if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY! + PanelID := pan.arrIdx; if not d2d then begin with gWalls[PanelID] do begin - if g_CollidePlayer(X, Y, Width, Height) or - g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit; - + if g_CollidePlayer(X, Y, Width, Height) or g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit; if not Enabled then begin if not NoSound then begin g_Sound_PlayExAt('SOUND_GAME_DOORCLOSE', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE'); end; - g_Map_EnableWall(PanelID); - Result := True; + g_Map_EnableWallGUID(PanelGUID); + result := true; end; end; end else begin - if gDoorMap = nil then Exit; + if (gDoorMap = nil) then exit; c := -1; for a := 0 to High(gDoorMap) do begin for b := 0 to High(gDoorMap[a]) do + begin if gDoorMap[a, b] = DWORD(PanelID) then begin c := a; - Break; + break; end; - - if c <> -1 then Break; + end; + if (c <> -1) then break; end; - if c = -1 then Exit; + if (c = -1) then exit; for b := 0 to High(gDoorMap[c]) do + begin with gWalls[gDoorMap[c, b]] do begin - if g_CollidePlayer(X, Y, Width, Height) or - g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit; + if g_CollidePlayer(X, Y, Width, Height) or g_Mons_IsAnyAliveAt(X, Y, Width, Height) then exit; end; + end; if not NoSound then + begin for b := 0 to High(gDoorMap[c]) do + begin if not gWalls[gDoorMap[c, b]].Enabled then begin with gWalls[PanelID] do begin g_Sound_PlayExAt('SOUND_GAME_DOORCLOSE', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE'); end; - Break; + break; end; + end; + end; for b := 0 to High(gDoorMap[c]) do + begin if not gWalls[gDoorMap[c, b]].Enabled then begin - g_Map_EnableWall(gDoorMap[c, b]); - Result := True; + g_Map_EnableWall_XXX(gDoorMap[c, b]); + result := true; end; + end; end; end; -procedure tr_CloseTrap(PanelID: Integer; NoSound: Boolean; d2d: Boolean); + +procedure tr_CloseTrap (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean); var a, b, c: Integer; wx, wy, wh, ww: Integer; + pan: TPanel; + PanelID: Integer; function monsDamage (mon: TMonster): Boolean; begin @@ -238,7 +237,19 @@ var end; begin - if PanelID = -1 then Exit; + pan := g_Map_PanelByGUID(PanelGUID); + { + if (pan = nil) then + begin + e_LogWritefln('tr_CloseTrap: pguid=%s; NO PANEL!', [PanelGUID], MSG_WARNING); + end + else + begin + e_LogWritefln('tr_CloseTrap: pguid=%s; isGWall=%s; arrIdx=%s', [PanelGUID, pan.isGWall, pan.arrIdx]); + end; + } + if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY! + PanelID := pan.arrIdx; if not d2d then begin @@ -247,8 +258,7 @@ begin if (not NoSound) and (not Enabled) then begin g_Sound_PlayExAt('SOUND_GAME_SWITCH1', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1'); end; end; @@ -260,20 +270,25 @@ begin with gWalls[PanelID] do begin if gPlayers <> nil then + begin for a := 0 to High(gPlayers) do - if (gPlayers[a] <> nil) and gPlayers[a].Live and - gPlayers[a].Collide(X, Y, Width, Height) then + begin + if (gPlayers[a] <> nil) and gPlayers[a].alive and gPlayers[a].Collide(X, Y, Width, Height) then + begin gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + end; + end; + end; //g_Mons_ForEach(monsDamage); g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage); - if not Enabled then g_Map_EnableWall(PanelID); + if not Enabled then g_Map_EnableWallGUID(PanelGUID); end; end else begin - if gDoorMap = nil then Exit; + if (gDoorMap = nil) then exit; c := -1; for a := 0 to High(gDoorMap) do @@ -283,13 +298,12 @@ begin if gDoorMap[a, b] = DWORD(PanelID) then begin c := a; - Break; + break; end; end; - - if c <> -1 then Break; + if (c <> -1) then break; end; - if c = -1 then Exit; + if (c = -1) then exit; if not NoSound then begin @@ -317,143 +331,166 @@ begin with gWalls[gDoorMap[c, b]] do begin if gPlayers <> nil then + begin for a := 0 to High(gPlayers) do - if (gPlayers[a] <> nil) and gPlayers[a].Live and - gPlayers[a].Collide(X, Y, Width, Height) then + begin + if (gPlayers[a] <> nil) and gPlayers[a].alive and gPlayers[a].Collide(X, Y, Width, Height) then + begin gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); + end; + end; + end; //g_Mons_ForEach(monsDamage); g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage); (* if gMonsters <> nil then for a := 0 to High(gMonsters) do - if (gMonsters[a] <> nil) and gMonsters[a].Live and + if (gMonsters[a] <> nil) and gMonsters[a].alive and g_Obj_Collide(X, Y, Width, Height, @gMonsters[a].Obj) then gMonsters[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP); *) - if not Enabled then g_Map_EnableWall(gDoorMap[c, b]); + if not Enabled then g_Map_EnableWall_XXX(gDoorMap[c, b]); end; end; end; end; -function tr_OpenDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; + +function tr_OpenDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean; var a, b, c: Integer; + pan: TPanel; + PanelID: Integer; begin - Result := False; - - if PanelID = -1 then Exit; + result := false; + pan := g_Map_PanelByGUID(PanelGUID); + if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY! + PanelID := pan.arrIdx; if not d2d then begin with gWalls[PanelID] do + begin if Enabled then begin if not NoSound then begin g_Sound_PlayExAt('SOUND_GAME_DOOROPEN', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN'); end; - g_Map_DisableWall(PanelID); - Result := True; + g_Map_DisableWallGUID(PanelGUID); + result := true; end; + end end else begin - if gDoorMap = nil then Exit; + if (gDoorMap = nil) then exit; c := -1; for a := 0 to High(gDoorMap) do begin for b := 0 to High(gDoorMap[a]) do + begin if gDoorMap[a, b] = DWORD(PanelID) then begin c := a; - Break; + break; end; - - if c <> -1 then Break; + end; + if (c <> -1) then break; end; - if c = -1 then Exit; + if (c = -1) then exit; if not NoSound then + begin for b := 0 to High(gDoorMap[c]) do + begin if gWalls[gDoorMap[c, b]].Enabled then begin with gWalls[PanelID] do begin g_Sound_PlayExAt('SOUND_GAME_DOOROPEN', X, Y); - if g_Game_IsServer and g_Game_IsNet then - MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN'); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN'); end; - Break; + break; end; + end; + end; for b := 0 to High(gDoorMap[c]) do + begin if gWalls[gDoorMap[c, b]].Enabled then begin - g_Map_DisableWall(gDoorMap[c, b]); - Result := True; + g_Map_DisableWall_XXX(gDoorMap[c, b]); + result := true; end; + end; end; end; -function tr_SetLift(PanelID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean; + +function tr_SetLift (PanelGUID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean; var - a, b, c, t: Integer; + a, b, c: Integer; + t: Integer = 0; + pan: TPanel; + PanelID: Integer; begin - t := 0; - Result := False; - - if PanelID = -1 then Exit; + result := false; + pan := g_Map_PanelByGUID(PanelGUID); + if (pan = nil) or not pan.isGLift then exit; //!FIXME!TRIGANY! + PanelID := pan.arrIdx; - if (gLifts[PanelID].PanelType = PANEL_LIFTUP) or - (gLifts[PanelID].PanelType = PANEL_LIFTDOWN) then + if (gLifts[PanelID].PanelType = PANEL_LIFTUP) or (gLifts[PanelID].PanelType = PANEL_LIFTDOWN) then + begin case d of 0: t := 0; 1: t := 1; else t := IfThen(gLifts[PanelID].LiftType = 1, 0, 1); end - else if (gLifts[PanelID].PanelType = PANEL_LIFTLEFT) or - (gLifts[PanelID].PanelType = PANEL_LIFTRIGHT) then + end + else if (gLifts[PanelID].PanelType = PANEL_LIFTLEFT) or (gLifts[PanelID].PanelType = PANEL_LIFTRIGHT) then + begin case d of 0: t := 2; 1: t := 3; else t := IfThen(gLifts[PanelID].LiftType = 2, 3, 2); end; + end; if not d2d then begin with gLifts[PanelID] do - if LiftType <> t then + begin + if (LiftType <> t) then begin - g_Map_SetLift(PanelID, t); - - {if not NoSound then - g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X, Y);} - Result := True; + g_Map_SetLiftGUID(PanelGUID, t); //??? + //if not NoSound then g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X, Y); + result := true; end; + end; end else // Êàê â D2d begin - if gLiftMap = nil then Exit; + if (gLiftMap = nil) then exit; c := -1; for a := 0 to High(gLiftMap) do begin for b := 0 to High(gLiftMap[a]) do - if gLiftMap[a, b] = DWORD(PanelID) then + begin + if (gLiftMap[a, b] = DWORD(PanelID)) then begin c := a; - Break; + break; end; - - if c <> -1 then Break; + end; + if (c <> -1) then break; end; - if c = -1 then Exit; + if (c = -1) then exit; {if not NoSound then for b := 0 to High(gLiftMap[c]) do @@ -465,27 +502,32 @@ begin end;} for b := 0 to High(gLiftMap[c]) do + begin with gLifts[gLiftMap[c, b]] do - if LiftType <> t then + begin + if (LiftType <> t) then begin - g_Map_SetLift(gLiftMap[c, b], t); - - Result := True; + g_Map_SetLift_XXX(gLiftMap[c, b], t); + result := true; end; + end; + end; end; end; -function tr_SpawnShot(ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer; + +function tr_SpawnShot (ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer; var snd: string; Projectile: Boolean; TextureID: DWORD; Anim: TAnimation; begin - Result := -1; + result := -1; TextureID := DWORD(-1); snd := 'SOUND_WEAPON_FIREROCKET'; - Projectile := True; + Projectile := true; + case ShotType of TRIGGER_SHOT_PISTOL: begin @@ -495,8 +537,7 @@ begin if ShotSound then begin g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); - if g_Game_IsNet then - MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); + if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); end; end; @@ -509,8 +550,7 @@ begin if ShotSound then begin g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET); - if g_Game_IsNet then - MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); + if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1); end; end; @@ -522,8 +562,7 @@ begin if ShotSound then begin g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); - if g_Game_IsNet then - MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL2); + if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL2); end; end; @@ -536,8 +575,7 @@ begin begin g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL); - if g_Game_IsNet then - MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL3); + if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL3); end; end; @@ -627,125 +665,118 @@ begin end; if g_Game_IsNet and g_Game_IsServer then + begin case ShotType of - TRIGGER_SHOT_EXPL: - MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_EXPLODE); - TRIGGER_SHOT_BFGEXPL: - MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_BFGEXPL); + TRIGGER_SHOT_EXPL: MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_EXPLODE); + TRIGGER_SHOT_BFGEXPL: MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_BFGEXPL); else begin - if Projectile then - MH_SEND_CreateShot(LastShotID); - if ShotSound then - MH_SEND_Sound(wx, wy, snd); + if Projectile then MH_SEND_CreateShot(LastShotID); + if ShotSound then MH_SEND_Sound(wx, wy, snd); end; end; + end; - if ShotSound then - g_Sound_PlayExAt(snd, wx, wy); + if ShotSound then g_Sound_PlayExAt(snd, wx, wy); - if Projectile then - Result := LastShotID; + if Projectile then Result := LastShotID; end; -procedure MakeShot(var Trigger: TTrigger; wx, wy, dx, dy: Integer; TargetUID: Word); + +procedure MakeShot (var Trigger: TTrigger; wx, wy, dx, dy: Integer; TargetUID: Word); begin with Trigger do - if (trigData.trigShotAmmo = 0) or - ((trigData.trigShotAmmo > 0) and (ShotAmmoCount > 0)) then + begin + if (trigData.trigAmmo = 0) or ((trigData.trigAmmo > 0) and (ShotAmmoCount > 0)) then begin - if (trigShotPanelID <> -1) and (ShotPanelTime = 0) then + if (trigShotPanelGUID <> -1) and (ShotPanelTime = 0) then begin - g_Map_SwitchTexture(ShotPanelType, trigShotPanelID); + g_Map_SwitchTextureGUID(ShotPanelType, trigShotPanelGUID); ShotPanelTime := 4; // òèêîâ íà âñïûøêó âûñòðåëà end; - if trigData.trigShotIntSight > 0 then - ShotSightTimeout := 180; // ~= 5 ñåêóíä + if (trigData.trigSight > 0) then ShotSightTimeout := 180; // ~= 5 ñåêóíä - if ShotAmmoCount > 0 then Dec(ShotAmmoCount); + if (ShotAmmoCount > 0) then Dec(ShotAmmoCount); - dx := dx + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy); - dy := dy + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy); + dx += Random(trigData.trigAccuracy)-Random(trigData.trigAccuracy); + dy += Random(trigData.trigAccuracy)-Random(trigData.trigAccuracy); - tr_SpawnShot(trigData.trigShotType, wx, wy, dx, dy, trigData.trigShotSound, TargetUID); + tr_SpawnShot(trigData.trigShotType, wx, wy, dx, dy, not trigData.trigQuiet, TargetUID); end else - if (trigData.trigShotIntReload > 0) and (ShotReloadTime = 0) then - ShotReloadTime := trigData.trigShotIntReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè + begin + if (trigData.trigReload > 0) and (ShotReloadTime = 0) then + begin + ShotReloadTime := trigData.trigReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè + end; + end; + end; end; -procedure tr_MakeEffect(X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean); + +procedure tr_MakeEffect (X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean); var FramesID: DWORD; Anim: TAnimation; begin if T = TRIGGER_EFFECT_PARTICLE then + begin case ST of TRIGGER_EFFECT_SLIQUID: begin - if (CR = 255) and (CG = 0) and (CB = 0) then - g_GFX_SimpleWater(X, Y, 1, VX, VY, 1, 0, 0, 0) - else if (CR = 0) and (CG = 255) and (CB = 0) then - g_GFX_SimpleWater(X, Y, 1, VX, VY, 2, 0, 0, 0) - else if (CR = 0) and (CG = 0) and (CB = 255) then - g_GFX_SimpleWater(X, Y, 1, VX, VY, 3, 0, 0, 0) - else - g_GFX_SimpleWater(X, Y, 1, VX, VY, 0, 0, 0, 0); + if (CR = 255) and (CG = 0) and (CB = 0) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 1, 0, 0, 0) + else if (CR = 0) and (CG = 255) and (CB = 0) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 2, 0, 0, 0) + else if (CR = 0) and (CG = 0) and (CB = 255) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 3, 0, 0, 0) + else g_GFX_SimpleWater(X, Y, 1, VX, VY, 0, 0, 0, 0); end; - TRIGGER_EFFECT_LLIQUID: - g_GFX_SimpleWater(X, Y, 1, VX, VY, 4, CR, CG, CB); - TRIGGER_EFFECT_DLIQUID: - g_GFX_SimpleWater(X, Y, 1, VX, VY, 5, CR, CG, CB); - TRIGGER_EFFECT_BLOOD: - g_GFX_Blood(X, Y, 1, VX, VY, 0, 0, CR, CG, CB); - TRIGGER_EFFECT_SPARK: - g_GFX_Spark(X, Y, 1, GetAngle2(VX, VY), 0, 0); - TRIGGER_EFFECT_BUBBLE: - g_GFX_Bubbles(X, Y, 1, 0, 0); + TRIGGER_EFFECT_LLIQUID: g_GFX_SimpleWater(X, Y, 1, VX, VY, 4, CR, CG, CB); + TRIGGER_EFFECT_DLIQUID: g_GFX_SimpleWater(X, Y, 1, VX, VY, 5, CR, CG, CB); + TRIGGER_EFFECT_BLOOD: g_GFX_Blood(X, Y, 1, VX, VY, 0, 0, CR, CG, CB); + TRIGGER_EFFECT_SPARK: g_GFX_Spark(X, Y, 1, GetAngle2(VX, VY), 0, 0); + TRIGGER_EFFECT_BUBBLE: g_GFX_Bubbles(X, Y, 1, 0, 0); end; + end; + if T = TRIGGER_EFFECT_ANIMATION then + begin case ST of EFFECT_TELEPORT: begin if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then begin Anim := TAnimation.Create(FramesID, False, 3); - if not Silent then - g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y); + if not Silent then g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y); g_GFX_OnceAnim(X-32, Y-32, Anim); Anim.Free(); end; - if Send and g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(X, Y, Byte(not Silent), NET_GFX_TELE); + if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X, Y, Byte(not Silent), NET_GFX_TELE); end; EFFECT_RESPAWN: begin if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then begin Anim := TAnimation.Create(FramesID, False, 4); - if not Silent then - g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y); + if not Silent then g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y); g_GFX_OnceAnim(X-16, Y-16, Anim); Anim.Free(); end; - if Send and g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(X-16, Y-16, Byte(not Silent), NET_GFX_RESPAWN); + if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-16, Y-16, Byte(not Silent), NET_GFX_RESPAWN); end; EFFECT_FIRE: begin if g_Frames_Get(FramesID, 'FRAMES_FIRE') then begin Anim := TAnimation.Create(FramesID, False, 4); - if not Silent then - g_Sound_PlayExAt('SOUND_FIRE', X, Y); + if not Silent then g_Sound_PlayExAt('SOUND_FIRE', X, Y); g_GFX_OnceAnim(X-32, Y-128, Anim); Anim.Free(); end; - if Send and g_Game_IsServer and g_Game_IsNet then - MH_SEND_Effect(X-32, Y-128, Byte(not Silent), NET_GFX_FIRE); + if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-32, Y-128, Byte(not Silent), NET_GFX_FIRE); end; end; + end; end; -function tr_Teleport(ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean; + +function tr_Teleport (ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean; var p: TPlayer; m: TMonster; @@ -756,56 +787,45 @@ begin UID_PLAYER: begin p := g_Player_Get(ActivateUID); - if p = nil then - Exit; - + if p = nil then Exit; if D2D then - begin - if p.TeleportTo(TX-(p.Obj.Rect.Width div 2), - TY-p.Obj.Rect.Height, - Silent, - TDir) then - Result := True; - end + begin + if p.TeleportTo(TX-(p.Obj.Rect.Width div 2), TY-p.Obj.Rect.Height, Silent, TDir) then result := true; + end else - if p.TeleportTo(TX, TY, Silent, TDir) then - Result := True; + begin + if p.TeleportTo(TX, TY, Silent, TDir) then result := true; + end; end; - UID_MONSTER: begin m := g_Monsters_ByUID(ActivateUID); - if m = nil then - Exit; - + if m = nil then Exit; if D2D then - begin - if m.TeleportTo(TX-(m.Obj.Rect.Width div 2), - TY-m.Obj.Rect.Height, - Silent, - TDir) then - Result := True; - end + begin + if m.TeleportTo(TX-(m.Obj.Rect.Width div 2), TY-m.Obj.Rect.Height, Silent, TDir) then result := true; + end else - if m.TeleportTo(TX, TY, Silent, TDir) then - Result := True; + begin + if m.TeleportTo(TX, TY, Silent, TDir) then result := true; + end; end; end; end; -function tr_Push(ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean; + +function tr_Push (ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean; var p: TPlayer; m: TMonster; begin - Result := True; - if (ActivateUID < 0) or (ActivateUID > $FFFF) then Exit; + result := true; + if (ActivateUID < 0) or (ActivateUID > $FFFF) then exit; case g_GetUIDType(ActivateUID) of UID_PLAYER: begin p := g_Player_Get(ActivateUID); - if p = nil then - Exit; + if p = nil then Exit; if ResetVel then begin @@ -821,8 +841,7 @@ begin UID_MONSTER: begin m := g_Monsters_ByUID(ActivateUID); - if m = nil then - Exit; + if m = nil then Exit; if ResetVel then begin @@ -837,7 +856,8 @@ begin end; end; -function tr_Message(MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean; + +function tr_Message (MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean; var msg: string; p: TPlayer; @@ -847,153 +867,158 @@ begin if (ActivateUID < 0) or (ActivateUID > $FFFF) then Exit; msg := b_Text_Format(MText); case MSendTo of - 0: // activator + TRIGGER_MESSAGE_DEST_ME: // activator begin if g_GetUIDType(ActivateUID) = UID_PLAYER then begin if g_Game_IsWatchedPlayer(ActivateUID) then begin - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); end else begin p := g_Player_Get(ActivateUID); if g_Game_IsNet and (p.FClientID >= 0) then - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM, p.FClientID) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, p.FClientID); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, p.FClientID) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, p.FClientID); + end; end; end; end; - 1: // activator's team + TRIGGER_MESSAGE_DEST_MY_TEAM: // activator's team begin if g_GetUIDType(ActivateUID) = UID_PLAYER then begin p := g_Player_Get(ActivateUID); if g_Game_IsWatchedTeam(p.Team) then - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); + end; if g_Game_IsNet then begin for i := Low(gPlayers) to High(gPlayers) do + begin if (gPlayers[i].Team = p.Team) and (gPlayers[i].FClientID >= 0) then - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + end; + end; end; end; end; - 2: // activator's enemy team + TRIGGER_MESSAGE_DEST_ENEMY_TEAM: // activator's enemy team begin if g_GetUIDType(ActivateUID) = UID_PLAYER then begin p := g_Player_Get(ActivateUID); if g_Game_IsWatchedTeam(p.Team) then - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); + end; if g_Game_IsNet then begin for i := Low(gPlayers) to High(gPlayers) do + begin if (gPlayers[i].Team <> p.Team) and (gPlayers[i].FClientID >= 0) then - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + end; + end; end; end; end; - 3: // red team + TRIGGER_MESSAGE_DEST_RED_TEAM: // red team begin if g_Game_IsWatchedTeam(TEAM_RED) then - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); + end; if g_Game_IsNet then begin for i := Low(gPlayers) to High(gPlayers) do + begin if (gPlayers[i].Team = TEAM_RED) and (gPlayers[i].FClientID >= 0) then - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + end; + end; end; end; - 4: // blue team + TRIGGER_MESSAGE_DEST_BLUE_TEAM: // blue team begin if g_Game_IsWatchedTeam(TEAM_BLUE) then - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); + end; if g_Game_IsNet then begin for i := Low(gPlayers) to High(gPlayers) do + begin if (gPlayers[i].Team = TEAM_BLUE) and (gPlayers[i].FClientID >= 0) then - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + begin + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID); + end; + end; end; end; - 5: // everyone + TRIGGER_MESSAGE_DEST_EVERYONE: // everyone begin - if MKind = 0 then - g_Console_Add(msg, True) - else if MKind = 1 then - g_Game_Message(msg, MTime); + if MKind = TRIGGER_MESSAGE_KIND_CHAT then g_Console_Add(msg, True) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then g_Game_Message(msg, MTime); if g_Game_IsNet then begin - if MKind = 0 then - MH_SEND_Chat(msg, NET_CHAT_SYSTEM) - else if MKind = 1 then - MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg); + if MKind = TRIGGER_MESSAGE_KIND_CHAT then MH_SEND_Chat(msg, NET_CHAT_SYSTEM) + else if MKind = TRIGGER_MESSAGE_KIND_GAME then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg); end; end; end; end; -function tr_ShotAimCheck(var Trigger: TTrigger; Obj: PObj): Boolean; + +function tr_ShotAimCheck (var Trigger: TTrigger; Obj: PObj): Boolean; begin result := false; with Trigger do begin - if TriggerType <> TRIGGER_SHOT then - Exit; - Result := (trigData.trigShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0) + if TriggerType <> TRIGGER_SHOT then Exit; + result := (trigData.trigAim and TRIGGER_SHOT_AIM_ALLMAP > 0) or g_Obj_Collide(X, Y, Width, Height, Obj); - if Result and (trigData.trigShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then - Result := g_TraceVector(trigData.trigShotPos.X, - trigData.trigShotPos.Y, + if result and (trigData.trigAim and TRIGGER_SHOT_AIM_TRACE > 0) then + begin + result := g_TraceVector(trigData.trigTX, trigData.trigTY, Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2), Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2)); + end; end; end; -function ActivateTrigger(var Trigger: TTrigger; actType: Byte): Boolean; + +function ActivateTrigger (var Trigger: TTrigger; actType: Byte): Boolean; var animonce: Boolean; p: TPlayer; m: TMonster; + pan: TPanel; idx, k, wx, wy, xd, yd: Integer; iid: LongWord; coolDown: Boolean; @@ -1008,7 +1033,7 @@ var function monsShotTarget (mon: TMonster): Boolean; begin result := false; // don't stop - if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + if mon.alive and tr_ShotAimCheck(Trigger, @(mon.Obj)) then begin xd := mon.GameX + mon.Obj.Rect.Width div 2; yd := mon.GameY + mon.Obj.Rect.Height div 2; @@ -1020,7 +1045,7 @@ var function monsShotTargetMonPlr (mon: TMonster): Boolean; begin result := false; // don't stop - if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + if mon.alive and tr_ShotAimCheck(Trigger, @(mon.Obj)) then begin xd := mon.GameX + mon.Obj.Rect.Width div 2; yd := mon.GameY + mon.Obj.Rect.Height div 2; @@ -1032,7 +1057,7 @@ var function monShotTargetPlrMon (mon: TMonster): Boolean; begin result := false; // don't stop - if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then + if mon.alive and tr_ShotAimCheck(Trigger, @(mon.Obj)) then begin xd := mon.GameX + mon.Obj.Rect.Width div 2; yd := mon.GameY + mon.Obj.Rect.Height div 2; @@ -1042,16 +1067,12 @@ var end; begin - Result := False; - if g_Game_IsClient then - Exit; + result := false; + if g_Game_IsClient then exit; - if not Trigger.Enabled then - Exit; - if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then - Exit; - if gLMSRespawn = LMS_RESPAWN_WARMUP then - Exit; + if not Trigger.Enabled then exit; + if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then exit; + if gLMSRespawn = LMS_RESPAWN_WARMUP then exit; animonce := False; @@ -1065,7 +1086,7 @@ begin g_Sound_PlayEx('SOUND_GAME_SWITCH0'); if g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH0'); gExitByTrigger := True; - g_Game_ExitLevel(trigData.trigMapName); + g_Game_ExitLevel(trigData.trigMap); TimeOut := 18; Result := True; @@ -1075,46 +1096,46 @@ begin TRIGGER_TELEPORT: begin Result := tr_Teleport(ActivateUID, - trigData.trigTargetPoint.X, trigData.trigTargetPoint.Y, - trigData.trigTlpDir, trigData.trigsilent_teleport, - trigData.trigd2d_teleport); + trigData.trigTarget.X, trigData.trigTarget.Y, + trigData.trigDirection, trigData.trigSilent, + trigData.trigD2d); TimeOut := 0; end; TRIGGER_OPENDOOR: begin - Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); + Result := tr_OpenDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); TimeOut := 0; end; TRIGGER_CLOSEDOOR: begin - Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); + Result := tr_CloseDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); TimeOut := 0; end; TRIGGER_DOOR, TRIGGER_DOOR5: begin - if trigPanelID <> -1 then + pan := g_Map_PanelByGUID(trigPanelGUID); + if (pan <> nil) and pan.isGWall then begin - if gWalls[trigPanelID].Enabled then - begin - Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); - - if TriggerType = TRIGGER_DOOR5 then - DoorTime := 180; - end + if gWalls[{trigPanelID}pan.arrIdx].Enabled then + begin + result := tr_OpenDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); + if (TriggerType = TRIGGER_DOOR5) then DoorTime := 180; + end else - Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); + begin + result := tr_CloseDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); + end; - if Result then - TimeOut := 18; + if result then TimeOut := 18; end; end; TRIGGER_CLOSETRAP, TRIGGER_TRAP: begin - tr_CloseTrap(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); + tr_CloseTrap(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); if TriggerType = TRIGGER_TRAP then begin @@ -1132,15 +1153,9 @@ begin TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: begin - PressCount := PressCount + 1; - - if PressTime = -1 then - PressTime := trigData.trigWait; - - if coolDown then - TimeOut := 18 - else - TimeOut := 0; + PressCount += 1; + if PressTime = -1 then PressTime := trigData.trigWait; + if coolDown then TimeOut := 18 else TimeOut := 0; Result := True; end; @@ -1159,10 +1174,10 @@ begin TRIGGER_LIFTUP: begin - Result := tr_SetLift(trigPanelID, 0, trigData.trigNoSound, trigData.trigd2d_doors); + Result := tr_SetLift(trigPanelGUID, 0, trigData.trigSilent, trigData.trigD2d); TimeOut := 0; - if (not trigData.trigNoSound) and Result then begin + if (not trigData.trigSilent) and Result then begin g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X + (Width div 2), Y + (Height div 2)); @@ -1175,10 +1190,10 @@ begin TRIGGER_LIFTDOWN: begin - Result := tr_SetLift(trigPanelID, 1, trigData.trigNoSound, trigData.trigd2d_doors); + Result := tr_SetLift(trigPanelGUID, 1, trigData.trigSilent, trigData.trigD2d); TimeOut := 0; - if (not trigData.trigNoSound) and Result then begin + if (not trigData.trigSilent) and Result then begin g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X + (Width div 2), Y + (Height div 2)); @@ -1191,13 +1206,13 @@ begin TRIGGER_LIFT: begin - Result := tr_SetLift(trigPanelID, 3, trigData.trigNoSound, trigData.trigd2d_doors); + Result := tr_SetLift(trigPanelGUID, 3, trigData.trigSilent, trigData.trigD2d); if Result then begin TimeOut := 18; - if (not trigData.trigNoSound) and Result then begin + if (not trigData.trigSilent) and Result then begin g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X + (Width div 2), Y + (Height div 2)); @@ -1222,7 +1237,7 @@ begin else TimeOut := 0; - animonce := trigData.trigAnimOnce; + animonce := trigData.trigAnimateOnce; Result := True; end; @@ -1250,10 +1265,10 @@ begin end; TRIGGER_SPAWNMONSTER: - if (trigData.trigMonType in [MONSTER_DEMON..MONSTER_MAN]) then + if (trigData.trigSpawnMonsType in [MONSTER_DEMON..MONSTER_MAN]) then begin Result := False; - if (trigData.trigMonDelay > 0) and (actType <> ACTIVATE_CUSTOM) then + if (trigData.trigDelay > 0) and (actType <> ACTIVATE_CUSTOM) then begin AutoSpawn := not AutoSpawn; SpawnCooldown := 0; @@ -1261,34 +1276,34 @@ begin Result := True; end; - if ((trigData.trigMonDelay = 0) and (actType <> ACTIVATE_CUSTOM)) - or ((trigData.trigMonDelay > 0) and (actType = ACTIVATE_CUSTOM)) then - for k := 1 to trigData.trigMonCount do + if ((trigData.trigDelay = 0) and (actType <> ACTIVATE_CUSTOM)) + or ((trigData.trigDelay > 0) and (actType = ACTIVATE_CUSTOM)) then + for k := 1 to trigData.trigMonsCount do begin - if (actType = ACTIVATE_CUSTOM) and (trigData.trigMonDelay > 0) then - SpawnCooldown := trigData.trigMonDelay; - if (trigData.trigMonMax > 0) and (SpawnedCount >= trigData.trigMonMax) then + if (actType = ACTIVATE_CUSTOM) and (trigData.trigDelay > 0) then + SpawnCooldown := trigData.trigDelay; + if (trigData.trigMax > 0) and (SpawnedCount >= trigData.trigMax) then Break; - mon := g_Monsters_Create(trigData.trigMonType, - trigData.trigMonPos.X, trigData.trigMonPos.Y, - TDirection(trigData.trigMonDir), True); + mon := g_Monsters_Create(trigData.trigSpawnMonsType, + trigData.trigTX, trigData.trigTY, + TDirection(trigData.trigDirection), True); Result := True; // Çäîðîâüå: - if (trigData.trigMonHealth > 0) then - mon.SetHealth(trigData.trigMonHealth); + if (trigData.trigHealth > 0) then + mon.SetHealth(trigData.trigHealth); // Óñòàíàâëèâàåì ïîâåäåíèå: - mon.MonsterBehaviour := trigData.trigMonBehav; + mon.MonsterBehaviour := trigData.trigBehaviour; mon.FNoRespawn := True; if g_Game_IsNet then MH_SEND_MonsterSpawn(mon.UID); // Èäåì èñêàòü öåëü, åñëè íàäî: - if trigData.trigMonActive then + if trigData.trigActive then mon.WakeUp(); - if trigData.trigMonType <> MONSTER_BARREL then Inc(gTotalMonsters); + if trigData.trigSpawnMonsType <> MONSTER_BARREL then Inc(gTotalMonsters); if g_Game_IsNet then begin @@ -1296,18 +1311,18 @@ begin gMonstersSpawned[High(gMonstersSpawned)] := mon.UID; end; - if trigData.trigMonMax > 0 then + if trigData.trigMax > 0 then begin mon.SpawnTrigger := ID; Inc(SpawnedCount); end; - case trigData.trigMonEffect of + case trigData.trigEffect of EFFECT_TELEPORT: begin if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then begin Anim := TAnimation.Create(FramesID, False, 3); - g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigMonPos.X, trigData.trigMonPos.Y); + g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-32, Anim); Anim.Free(); @@ -1321,7 +1336,7 @@ begin if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then begin Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigMonPos.X, trigData.trigMonPos.Y); + g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-16, mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-16, Anim); Anim.Free(); @@ -1335,7 +1350,7 @@ begin if g_Frames_Get(FramesID, 'FRAMES_FIRE') then begin Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_FIRE', trigData.trigMonPos.X, trigData.trigMonPos.Y); + g_Sound_PlayExAt('SOUND_FIRE', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32, mon.Obj.Y+mon.Obj.Rect.Y+mon.Obj.Rect.Height-128, Anim); Anim.Free(); @@ -1363,10 +1378,10 @@ begin end; TRIGGER_SPAWNITEM: - if (trigData.trigItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then + if (trigData.trigSpawnItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then begin Result := False; - if (trigData.trigItemDelay > 0) and (actType <> ACTIVATE_CUSTOM) then + if (trigData.trigDelay > 0) and (actType <> ACTIVATE_CUSTOM) then begin AutoSpawn := not AutoSpawn; SpawnCooldown := 0; @@ -1374,36 +1389,36 @@ begin Result := True; end; - if ((trigData.trigItemDelay = 0) and (actType <> ACTIVATE_CUSTOM)) - or ((trigData.trigItemDelay > 0) and (actType = ACTIVATE_CUSTOM)) then - if (not trigData.trigItemOnlyDM) or + if ((trigData.trigDelay = 0) and (actType <> ACTIVATE_CUSTOM)) + or ((trigData.trigDelay > 0) and (actType = ACTIVATE_CUSTOM)) then + if (not trigData.trigDmonly) or (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then for k := 1 to trigData.trigItemCount do begin - if (actType = ACTIVATE_CUSTOM) and (trigData.trigItemDelay > 0) then - SpawnCooldown := trigData.trigItemDelay; - if (trigData.trigItemMax > 0) and (SpawnedCount >= trigData.trigItemMax) then + if (actType = ACTIVATE_CUSTOM) and (trigData.trigDelay > 0) then + SpawnCooldown := trigData.trigDelay; + if (trigData.trigMax > 0) and (SpawnedCount >= trigData.trigMax) then Break; - iid := g_Items_Create(trigData.trigItemPos.X, trigData.trigItemPos.Y, - trigData.trigItemType, trigData.trigItemFalls, False, True); + iid := g_Items_Create(trigData.trigTX, trigData.trigTY, + trigData.trigSpawnItemType, trigData.trigGravity, False, True); Result := True; - if trigData.trigItemMax > 0 then + if trigData.trigMax > 0 then begin it := g_Items_ByIdx(iid); it.SpawnTrigger := ID; Inc(SpawnedCount); end; - case trigData.trigItemEffect of + case trigData.trigEffect of EFFECT_TELEPORT: begin it := g_Items_ByIdx(iid); if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then begin Anim := TAnimation.Create(FramesID, False, 3); - g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigItemPos.X, trigData.trigItemPos.Y); + g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, Anim); Anim.Free(); @@ -1418,7 +1433,7 @@ begin if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then begin Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigItemPos.X, trigData.trigItemPos.Y); + g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16, it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, Anim); Anim.Free(); @@ -1433,7 +1448,7 @@ begin if g_Frames_Get(FramesID, 'FRAMES_FIRE') then begin Anim := TAnimation.Create(FramesID, False, 4); - g_Sound_PlayExAt('SOUND_FIRE', trigData.trigItemPos.X, trigData.trigItemPos.Y); + g_Sound_PlayExAt('SOUND_FIRE', trigData.trigTX, trigData.trigTY); g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32, it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, Anim); Anim.Free(); @@ -1468,18 +1483,15 @@ begin gMusic.Play(); end; - if Trigger.trigData.trigMusicAction = 1 then - begin // Âêëþ÷èòü + case Trigger.trigData.trigMusicAction of + TRIGGER_MUSIC_ACTION_STOP: // Âûêëþ÷èòü + gMusic.SpecPause := True; // Ïàóçà + TRIGGER_MUSIC_ACTION_PLAY: // Âêëþ÷èòü if gMusic.SpecPause then // Áûëà íà ïàóçå => èãðàòü gMusic.SpecPause := False else // Èãðàëà => ñíà÷àëà gMusic.SetPosition(0); - end - else // Âûêëþ÷èòü - begin - // Ïàóçà: - gMusic.SpecPause := True; - end; + end; if coolDown then TimeOut := 36 @@ -1491,11 +1503,11 @@ begin TRIGGER_PUSH: begin - pAngle := -DegToRad(trigData.trigPushAngle); + pAngle := -DegToRad(trigData.trigAngle); Result := tr_Push(ActivateUID, - Floor(Cos(pAngle)*trigData.trigPushForce), - Floor(Sin(pAngle)*trigData.trigPushForce), - trigData.trigResetVel); + Floor(Cos(pAngle)*trigData.trigForce), + Floor(Sin(pAngle)*trigData.trigForce), + trigData.trigResetVelocity); TimeOut := 0; end; @@ -1503,19 +1515,20 @@ begin begin Result := False; // Ïðèáàâèòü èëè îòíÿòü î÷êî - if (trigData.trigScoreAction in [0..1]) and (trigData.trigScoreCount > 0) then + if (trigData.trigScoreAction in [TRIGGER_SCORE_ACTION_ADD, TRIGGER_SCORE_ACTION_SUB]) and (trigData.trigScoreCount > 0) then begin // Ñâîåé èëè ÷óæîé êîìàíäå - if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then + if (trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then begin p := g_Player_Get(ActivateUID); - if ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) - or ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then + if ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) + or ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then begin Inc(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Scores if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1526,6 +1539,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+re'); end; + end; if trigData.trigScoreMsg then begin @@ -1534,13 +1548,14 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED); end; end; - if ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) - or ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then + if ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) + or ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then begin Dec(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Fouls if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1551,6 +1566,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-re'); end; + end; if trigData.trigScoreMsg then begin @@ -1559,13 +1575,14 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED); end; end; - if ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) - or ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then + if ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) + or ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then begin Inc(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Scores if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1576,6 +1593,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+be'); end; + end; if trigData.trigScoreMsg then begin @@ -1584,13 +1602,14 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE); end; end; - if ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) - or ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then + if ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) + or ((trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then begin Dec(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Fouls if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1601,6 +1620,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-be'); end; + end; if trigData.trigScoreMsg then begin @@ -1612,9 +1632,9 @@ begin Result := (p.Team = TEAM_RED) or (p.Team = TEAM_BLUE); end; // Êàêîé-òî êîíêðåòíîé êîìàíäå - if trigData.trigScoreTeam in [2..3] then + if trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_RED, TRIGGER_SCORE_TEAM_FORCE_BLUE] then begin - if (trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 2) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then begin Inc(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Scores @@ -1632,7 +1652,7 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED); end; end; - if (trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 2) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then begin Dec(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Fouls @@ -1650,7 +1670,7 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED); end; end; - if (trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 3) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_ADD) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then begin Inc(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Scores @@ -1668,7 +1688,7 @@ begin MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE); end; end; - if (trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 3) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_SUB) and (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then begin Dec(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Fouls @@ -1690,20 +1710,22 @@ begin end; end; // Âûèãðûø - if (trigData.trigScoreAction = 2) and (gGameSettings.GoalLimit > 0) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_WIN) and (gGameSettings.GoalLimit > 0) then begin // Ñâîåé èëè ÷óæîé êîìàíäû - if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then + if (trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then begin p := g_Player_Get(ActivateUID); - if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) // Red Wins - or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then + if ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) // Red Wins + or ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then + begin if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit; if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_OWN], [p.Name, _lc[I_PLAYER_SCORE_TO_RED]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1714,17 +1736,21 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wre'); end; + end; Result := True; end; - if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Blue Wins - or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then + end; + if ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) // Blue Wins + or ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then + begin if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit; if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + begin + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_OWN], [p.Name, _lc[I_PLAYER_SCORE_TO_BLUE]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1735,42 +1761,48 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wbe'); end; + end; Result := True; end; + end; end; // Êàêîé-òî êîíêðåòíîé êîìàíäû - if trigData.trigScoreTeam in [2..3] then + if trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_RED, TRIGGER_SCORE_TEAM_FORCE_BLUE] then begin - if trigData.trigScoreTeam = 2 then // Red Wins + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then // Red Wins + begin if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit; Result := True; end; - if trigData.trigScoreTeam = 3 then // Blue Wins + end; + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then // Blue Wins + begin if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit; Result := True; end; + end; end; end; // Ïðîèãðûø - if (trigData.trigScoreAction = 3) and (gGameSettings.GoalLimit > 0) then + if (trigData.trigScoreAction = TRIGGER_SCORE_ACTION_LOOSE) and (gGameSettings.GoalLimit > 0) then begin // Ñâîåé èëè ÷óæîé êîìàíäû - if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then + if (trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then begin p := g_Player_Get(ActivateUID); - if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Red Wins - or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then + if ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) // Red Wins + or ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit; if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + if trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_ENEMY], [p.Name, _lc[I_PLAYER_SCORE_TO_RED]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1784,14 +1816,14 @@ begin Result := True; end; - if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) // Blue Wins - or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then + if ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) // Blue Wins + or ((trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit; if trigData.trigScoreCon then - if trigData.trigScoreTeam = 0 then + if trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED then begin g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_ENEMY], [p.Name, _lc[I_PLAYER_SCORE_TO_BLUE]]), True); if g_Game_IsServer and g_Game_IsNet then @@ -1807,20 +1839,24 @@ begin end; end; // Êàêîé-òî êîíêðåòíîé êîìàíäû - if trigData.trigScoreTeam in [2..3] then + if trigData.trigScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_BLUE, TRIGGER_SCORE_TEAM_FORCE_RED] then begin - if trigData.trigScoreTeam = 3 then // Red Wins + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then // Red Wins + begin if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit; Result := True; end; - if trigData.trigScoreTeam = 2 then // Blue Wins + end; + if (trigData.trigScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then // Blue Wins + begin if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then begin gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit; Result := True; end; + end; end; end; if Result then begin @@ -1835,8 +1871,8 @@ begin TRIGGER_MESSAGE: begin - Result := tr_Message(trigData.trigMessageKind, trigData.trigMessageText, - trigData.trigMessageSendTo, trigData.trigMessageTime, + Result := tr_Message(trigData.trigKind, trigData.trigText, + trigData.trigMsgDest, trigData.trigMsgTime, ActivateUID); TimeOut := 18; end; @@ -1867,7 +1903,7 @@ begin end else begin // Óæå âèäåëè åãî // Åñëè èíòåðâàë îòêëþ÷¸í, íî îí âñ¸ åù¸ â çîíå ïîðàæåíèÿ, äà¸ì åìó âðåìÿ - if (trigData.trigDamageInterval = 0) and (Activators[k].TimeOut > 0) then + if (trigData.trigInterval = 0) and (Activators[k].TimeOut > 0) then Activators[k].TimeOut := 65535; // Òàéìàóò ïðîø¸ë - ðàáîòàåì Result := Activators[k].TimeOut = 0; @@ -1884,12 +1920,12 @@ begin Exit; // Íàíîñèì óðîí èãðîêó - if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigDamageValue > 0) then - p.Damage(trigData.trigDamageValue, 0, 0, 0, HIT_SOME); + if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigAmount > 0) then + p.Damage(trigData.trigAmount, 0, 0, 0, HIT_SOME); // Ëå÷èì èãðîêà - if (TriggerType = TRIGGER_HEALTH) and (trigData.trigHealValue > 0) then - if p.Heal(trigData.trigHealValue, not trigData.trigHealMax) and (not trigData.trigHealSilent) then + if (TriggerType = TRIGGER_HEALTH) and (trigData.trigAmount > 0) then + if p.Heal(trigData.trigAmount, not trigData.trigHealMax) and (not trigData.trigSilent) then begin g_Sound_PlayExAt('SOUND_ITEM_GETITEM', p.Obj.X, p.Obj.Y); if g_Game_IsServer and g_Game_IsNet then @@ -1904,12 +1940,12 @@ begin Exit; // Íàíîñèì óðîí ìîíñòðó - if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigDamageValue > 0) then - m.Damage(trigData.trigDamageValue, 0, 0, 0, HIT_SOME); + if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigAmount > 0) then + m.Damage(trigData.trigAmount, 0, 0, 0, HIT_SOME); // Ëå÷èì ìîíñòðà - if (TriggerType = TRIGGER_HEALTH) and (trigData.trigHealValue > 0) then - if m.Heal(trigData.trigHealValue) and (not trigData.trigHealSilent) then + if (TriggerType = TRIGGER_HEALTH) and (trigData.trigAmount > 0) then + if m.Heal(trigData.trigAmount) and (not trigData.trigSilent) then begin g_Sound_PlayExAt('SOUND_ITEM_GETITEM', m.Obj.X, m.Obj.Y); if g_Game_IsServer and g_Game_IsNet then @@ -1918,10 +1954,7 @@ begin end; end; // Íàçíà÷àåì âðåìÿ ñëåäóþùåãî âîçäåéñòâèÿ - if TriggerType = TRIGGER_DAMAGE then - idx := trigData.trigDamageInterval - else - idx := trigData.trigHealInterval; + idx := trigData.trigInterval; if coolDown then if idx > 0 then Activators[k].TimeOut := idx @@ -1938,11 +1971,11 @@ begin Exit; // put this at the beginning so it doesn't trigger itself - TimeOut := trigData.trigShotWait + 1; + TimeOut := trigData.trigWait + 1; - wx := trigData.trigShotPos.X; - wy := trigData.trigShotPos.Y; - pAngle := -DegToRad(trigData.trigShotAngle); + wx := trigData.trigTX; + wy := trigData.trigTY; + pAngle := -DegToRad(trigData.trigAngle); xd := wx + Round(Cos(pAngle) * 32.0); yd := wy + Round(Sin(pAngle) * 32.0); TargetUID := 0; @@ -1955,7 +1988,7 @@ begin TRIGGER_SHOT_TARGET_PLR: // players if gPlayers <> nil then for idx := Low(gPlayers) to High(gPlayers) do - if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + if (gPlayers[idx] <> nil) and gPlayers[idx].alive and tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin xd := gPlayers[idx].GameX + PLAYER_RECT_CX; @@ -1967,7 +2000,7 @@ begin TRIGGER_SHOT_TARGET_RED: // red team if gPlayers <> nil then for idx := Low(gPlayers) to High(gPlayers) do - if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + if (gPlayers[idx] <> nil) and gPlayers[idx].alive and (gPlayers[idx].Team = TEAM_RED) and tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin @@ -1980,7 +2013,7 @@ begin TRIGGER_SHOT_TARGET_BLUE: // blue team if gPlayers <> nil then for idx := Low(gPlayers) to High(gPlayers) do - if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + if (gPlayers[idx] <> nil) and gPlayers[idx].alive and (gPlayers[idx].Team = TEAM_BLUE) and tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin @@ -1997,7 +2030,7 @@ begin if (TargetUID = 0) and (gPlayers <> nil) then for idx := Low(gPlayers) to High(gPlayers) do - if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + if (gPlayers[idx] <> nil) and gPlayers[idx].alive and tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin xd := gPlayers[idx].GameX + PLAYER_RECT_CX; @@ -2011,7 +2044,7 @@ begin begin if gPlayers <> nil then for idx := Low(gPlayers) to High(gPlayers) do - if (gPlayers[idx] <> nil) and gPlayers[idx].Live and + if (gPlayers[idx] <> nil) and gPlayers[idx].alive and tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then begin xd := gPlayers[idx].GameX + PLAYER_RECT_CX; @@ -2037,13 +2070,13 @@ begin ((trigData.trigShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then begin Result := True; - if (trigData.trigShotIntSight = 0) or + if (trigData.trigSight = 0) or (trigData.trigShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID = ShotSightTarget) then MakeShot(Trigger, wx, wy, xd, yd, TargetUID) else begin - ShotSightTime := trigData.trigShotIntSight; + ShotSightTime := trigData.trigSight; ShotSightTargetN := TargetUID; if trigData.trigShotType = TRIGGER_SHOT_BFG then begin @@ -2077,30 +2110,57 @@ begin wy := Y + Height div 2; end; end; - xd := trigData.trigFXVelX; - yd := trigData.trigFXVelY; - if trigData.trigFXSpreadL > 0 then xd := xd - Random(trigData.trigFXSpreadL + 1); - if trigData.trigFXSpreadR > 0 then xd := xd + Random(trigData.trigFXSpreadR + 1); - if trigData.trigFXSpreadU > 0 then yd := yd - Random(trigData.trigFXSpreadU + 1); - if trigData.trigFXSpreadD > 0 then yd := yd + Random(trigData.trigFXSpreadD + 1); + xd := trigData.trigVelX; + yd := trigData.trigVelY; + if trigData.trigSpreadL > 0 then xd -= Random(trigData.trigSpreadL+1); + if trigData.trigSpreadR > 0 then xd += Random(trigData.trigSpreadR+1); + if trigData.trigSpreadU > 0 then yd -= Random(trigData.trigSpreadU+1); + if trigData.trigSpreadD > 0 then yd += Random(trigData.trigSpreadD+1); tr_MakeEffect(wx, wy, xd, yd, trigData.trigFXType, trigData.trigFXSubType, - trigData.trigFXColorR, trigData.trigFXColorG, trigData.trigFXColorB, True, False); + trigData.trigFXRed, trigData.trigFXGreen, trigData.trigFXBlue, True, False); Dec(idx); end; - TimeOut := trigData.trigFXWait; + TimeOut := trigData.trigWait; end; end; end; - if Result and (Trigger.TexturePanel <> -1) then - g_Map_SwitchTexture(Trigger.TexturePanelType, Trigger.TexturePanel, IfThen(animonce, 2, 1)); + if Result {and (Trigger.TexturePanel <> -1)} then + begin + g_Map_SwitchTextureGUID(Trigger.TexturePanelType, Trigger.TexturePanelGUID, IfThen(animonce, 2, 1)); + end; +end; + + +function g_Triggers_CreateWithMapIndex (Trigger: TTrigger; arridx, mapidx: Integer): DWORD; +var + triggers: TDynField; +begin + triggers := gCurrentMap['trigger']; + if (triggers = nil) then raise Exception.Create('LOAD: map has no triggers'); + if (mapidx < 0) or (mapidx >= triggers.count) then raise Exception.Create('LOAD: invalid map trigger index'); + Trigger.trigData := triggers.itemAt[mapidx]; + if (Trigger.trigData = nil) then raise Exception.Create('LOAD: internal error in trigger loader'); + Trigger.mapId := Trigger.trigData.id; + Trigger.mapIndex := mapidx; + if (Trigger.trigData.trigRec <> nil) then + begin + Trigger.trigData := Trigger.trigData.trigRec.clone({Trigger.trigData.headerRec}nil); + end + else + begin + Trigger.trigData := nil; + end; + result := g_Triggers_Create(Trigger, arridx); end; -function g_Triggers_Create(Trigger: TTrigger): DWORD; + +function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD; var find_id: DWORD; - fn, mapw: String; + fn, mapw: AnsiString; + f, olen: Integer; begin // Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà: if (Trigger.TriggerType = TRIGGER_EXIT) and @@ -2117,9 +2177,24 @@ begin if Trigger.TriggerType = TRIGGER_SECRET then gSecretsCount := gSecretsCount + 1; - find_id := FindTrigger(); + if (forceInternalIndex < 0) then + begin + find_id := FindTrigger(); + end + else + begin + olen := Length(gTriggers); + if (forceInternalIndex >= olen) then + begin + SetLength(gTriggers, forceInternalIndex+1); + for f := olen to High(gTriggers) do gTriggers[f].TriggerType := TRIGGER_NONE; + end; + find_id := DWORD(forceInternalIndex); + end; gTriggers[find_id] := Trigger; + //e_LogWritefln('created trigger with map index %s, findid=%s (%s)', [Trigger.mapIndex, find_id, Trigger.mapId]); + { writeln('trigger #', find_id, ': pos=(', Trigger.x, ',', Trigger.y, ')-(', Trigger.width, 'x', Trigger.height, ')', '; TexturePanel=', Trigger.TexturePanel, @@ -2222,7 +2297,7 @@ begin ShotSightTimeout := 0; ShotSightTarget := 0; ShotSightTargetN := 0; - ShotAmmoCount := Trigger.trigData.trigShotAmmo; + ShotAmmoCount := Trigger.trigData.trigAmmo; ShotReloadTime := 0; end; @@ -2254,6 +2329,7 @@ var var mon: TMonster; + pan: TPanel; begin if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create(); @@ -2266,120 +2342,135 @@ begin // Åñòü òðèããåð: if TriggerType <> TRIGGER_NONE then begin - // Óìåíüøàåì âðåìÿ äî çàêðûòèÿ äâåðè (îòêðûòèÿ ëîâóøêè): - if DoorTime > 0 then - DoorTime := DoorTime - 1; - // Óìåíüøàåì âðåìÿ îæèäàíèÿ ïîñëå íàæàòèÿ: - if PressTime > 0 then - PressTime := PressTime - 1; - // Ïðîâåðÿåì èãðîêîâ è ìîíñòðîâ, êîòîðûõ ðàíåå çàïîìíèëè: + // Óìåíüøàåì âðåìÿ äî çàêðûòèÿ äâåðè (îòêðûòèÿ ëîâóøêè) + if DoorTime > 0 then DoorTime := DoorTime - 1; + // Óìåíüøàåì âðåìÿ îæèäàíèÿ ïîñëå íàæàòèÿ + if PressTime > 0 then PressTime := PressTime - 1; + // Ïðîâåðÿåì èãðîêîâ è ìîíñòðîâ, êîòîðûõ ðàíåå çàïîìíèëè: if (TriggerType = TRIGGER_DAMAGE) or (TriggerType = TRIGGER_HEALTH) then + begin for b := 0 to High(Activators) do begin // Óìåíüøàåì âðåìÿ äî ïîâòîðíîãî âîçäåéñòâèÿ: if Activators[b].TimeOut > 0 then - Dec(Activators[b].TimeOut) + begin + Dec(Activators[b].TimeOut); + end else - Continue; + begin + continue; + end; // Ñ÷èòàåì, ÷òî îáúåêò ïîêèíóë çîíó äåéñòâèÿ òðèããåðà - if (trigData.trigDamageInterval = 0) and (Activators[b].TimeOut < 65530) then - Activators[b].TimeOut := 0; + if (trigData.trigInterval = 0) and (Activators[b].TimeOut < 65530) then Activators[b].TimeOut := 0; end; + end; - // Îáðàáàòûâàåì ñïàâíåðû: + // Îáðàáàòûâàåì ñïàâíåðû if Enabled and AutoSpawn then + begin if SpawnCooldown = 0 then begin - // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà: - if (TriggerType = TRIGGER_SPAWNMONSTER) and (trigData.trigMonDelay > 0) then + // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà + if (TriggerType = TRIGGER_SPAWNMONSTER) and (trigData.trigDelay > 0) then begin ActivateUID := 0; ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM); end; - // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò: - if (TriggerType = TRIGGER_SPAWNITEM) and (trigData.trigItemDelay > 0) then + // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò + if (TriggerType = TRIGGER_SPAWNITEM) and (trigData.trigDelay > 0) then begin ActivateUID := 0; ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM); end; - end else // Óìåíüøàåì âðåìÿ îæèäàíèÿ: + end + else + begin + // Óìåíüøàåì âðåìÿ îæèäàíèÿ Dec(SpawnCooldown); + end; + end; - // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü": + // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü" if TriggerType = TRIGGER_SHOT then begin if ShotPanelTime > 0 then begin Dec(ShotPanelTime); - if ShotPanelTime = 0 then - g_Map_SwitchTexture(ShotPanelType, trigShotPanelID); + if ShotPanelTime = 0 then g_Map_SwitchTextureGUID(ShotPanelType, trigShotPanelGUID); end; if ShotSightTime > 0 then begin Dec(ShotSightTime); - if ShotSightTime = 0 then - ShotSightTarget := ShotSightTargetN; + if ShotSightTime = 0 then ShotSightTarget := ShotSightTargetN; end; if ShotSightTimeout > 0 then begin Dec(ShotSightTimeout); - if ShotSightTimeout = 0 then - ShotSightTarget := 0; + if ShotSightTimeout = 0 then ShotSightTarget := 0; end; if ShotReloadTime > 0 then begin Dec(ShotReloadTime); - if ShotReloadTime = 0 then - ShotAmmoCount := trigData.trigShotAmmo; + if ShotReloadTime = 0 then ShotAmmoCount := trigData.trigAmmo; end; end; - // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì: + // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì if Enabled and (TriggerType = TRIGGER_SOUND) and (Sound <> nil) then + begin if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then begin - if trigData.trigPlayCount > 0 then // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî - SoundPlayCount := SoundPlayCount - 1; + if trigData.trigPlayCount > 0 then SoundPlayCount -= 1; // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî if trigData.trigLocal then - Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0) + begin + Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0); + end else + begin Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0); - if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then - MH_SEND_TriggerSound(gTriggers[a]); + end; + if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then MH_SEND_TriggerSound(gTriggers[a]); end; + end; - // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü: - if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (trigPanelID <> -1) then + // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü + if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then begin - tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors); + tr_OpenDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d); DoorTime := -1; end; - // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü: - if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (trigPanelID <> -1) then + // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü + if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then begin - // Óæå çàêðûòà: - if gWalls[trigPanelID].Enabled then - DoorTime := -1 - else // Ïîêà îòêðûòà - çàêðûâàåì - if tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors) then + pan := g_Map_PanelByGUID(trigPanelGUID); + if (pan <> nil) and pan.isGWall then + begin + // Óæå çàêðûòà + if {gWalls[trigPanelID].Enabled} pan.Enabled then + begin DoorTime := -1; + end + else + begin + // Ïîêà îòêðûòà - çàêðûâàåì + if tr_CloseDoor(trigPanelGUID, trigData.trigSilent, trigData.trigD2d) then DoorTime := -1; + end; + end; end; // Òðèããåð - ðàñøèðèòåëü èëè ïåðåêëþ÷àòåëü, è ïðîøëà çàäåðæêà, è íàæàëè íóæíîå ÷èñëî ðàç: if (TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF]) and - (PressTime = 0) and (PressCount >= trigData.trigCount) then + (PressTime = 0) and (PressCount >= trigData.trigPressCount) then begin - // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè: + // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè: PressTime := -1; - // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé: - if trigData.trigCount > 0 then - PressCount := PressCount - trigData.trigCount - else - PressCount := 0; + // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé: + if trigData.trigPressCount > 0 then PressCount -= trigData.trigPressCount else PressCount := 0; - // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû: + // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû: for b := 0 to High(gTriggers) do + begin if g_Collide(trigData.trigtX, trigData.trigtY, trigData.trigtWidth, trigData.trigtHeight, gTriggers[b].X, gTriggers[b].Y, gTriggers[b].Width, gTriggers[b].Height) and ((b <> a) or (trigData.trigWait > 0)) then @@ -2390,7 +2481,22 @@ begin Affected[High(Affected)] := b; end; end; - // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì: + end; + + //HACK! + // if we have panelid, assume that it will switch the moving platform + pan := g_Map_PanelByGUID(trigPanelGUID); + if (pan <> nil) then + begin + case TriggerType of + TRIGGER_PRESS: pan.movingActive := true; // what to do here? + TRIGGER_ON: pan.movingActive := true; + TRIGGER_OFF: pan.movingActive := false; + TRIGGER_ONOFF: pan.movingActive := not pan.movingActive; + end; + end; + + // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì: if (TriggerType = TRIGGER_PRESS) and trigData.trigExtRandom then begin if (Length(Affected) > 0) then @@ -2401,6 +2507,7 @@ begin end; end else //  ïðîòèâíîì ñëó÷àå ðàáîòàåì êàê îáû÷íî: + begin for i := 0 to High(Affected) do begin b := Affected[i]; @@ -2439,6 +2546,7 @@ begin end; end; end; + end; SetLength(Affected, 0); end; @@ -2461,7 +2569,7 @@ begin if gPlayers[b] <> nil then with gPlayers[b] do // Æèâ, åñòü íóæíûå êëþ÷è è îí ðÿäîì: - if Live and ((gTriggers[a].Keys and GetKeys) = gTriggers[a].Keys) and + if alive and ((gTriggers[a].Keys and GetKeys) = gTriggers[a].Keys) and Collide(X, Y, Width, Height) then begin gTriggers[a].ActivateUID := UID; @@ -2518,6 +2626,7 @@ end; procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0); begin + if (ID >= Length(gTriggers)) then exit; gTriggers[ID].ActivateUID := ActivateUID; ActivateTrigger(gTriggers[ID], ActivateType); end; @@ -2656,15 +2765,19 @@ begin b := False; for a := 0 to High(gTriggers) do + begin with gTriggers[a] do + begin if (TriggerType = TRIGGER_OPENDOOR) or (TriggerType = TRIGGER_DOOR5) or (TriggerType = TRIGGER_DOOR) then begin - tr_OpenDoor(trigPanelID, True, trigData.trigd2d_doors); + tr_OpenDoor(trigPanelGUID, True, trigData.trigD2d); if TriggerType = TRIGGER_DOOR5 then DoorTime := 180; b := True; end; + end; + end; if b then g_Sound_PlayEx('SOUND_GAME_DOOROPEN'); end; @@ -2708,31 +2821,30 @@ var dw: DWORD; sg: Single; b: Boolean; - //p: Pointer; begin -// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ: - count := 0; - if gTriggers <> nil then - for i := 0 to High(gTriggers) do - count := count + 1; + // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ + count := Length(gTriggers); Mem := TBinMemoryWriter.Create((count+1) * 200); -// Êîëè÷åñòâî òðèããåðîâ: + // Êîëè÷åñòâî òðèããåðîâ: Mem.WriteInt(count); - if count = 0 then - Exit; + //e_LogWritefln('saving %s triggers (count=%s)', [Length(gTriggers), count]); + + if count = 0 then exit; for i := 0 to High(gTriggers) do begin // Ñèãíàòóðà òðèããåðà: - dw := TRIGGER_SIGNATURE; // 'TRGR' + dw := TRIGGER_SIGNATURE; // 'TRGX' Mem.WriteDWORD(dw); // Òèï òðèããåðà: Mem.WriteByte(gTriggers[i].TriggerType); - // Ñïåöèàëüíûå äàííûå òðèããåðà: - //!!!FIXME!!! + if (gTriggers[i].TriggerType = TRIGGER_NONE) then continue; // empty one + // Ñïåöèàëüíûå äàííûå òðèããåðà: äà â æîïó, ïîòîì èç êàðòû îïÿòü âûòàùèì; ñîõðàíèì òîëüêî èíäåêñ + //e_LogWritefln('=== trigger #%s saved ===', [gTriggers[i].mapIndex]); + Mem.WriteInt(gTriggers[i].mapIndex); //p := @gTriggers[i].Data; //Mem.WriteMemory(p, SizeOf(TTriggerData)); // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà: @@ -2748,9 +2860,11 @@ begin // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè: Mem.WriteByte(gTriggers[i].Keys); // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ: - Mem.WriteInt(gTriggers[i].TexturePanel); + Mem.WriteInt(gTriggers[i].TexturePanelGUID); // Òèï ýòîé ïàíåëè: Mem.WriteWord(gTriggers[i].TexturePanelType); + // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû) + Mem.WriteInt(gTriggers[i].trigPanelGUID); // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè: Mem.WriteWord(gTriggers[i].TimeOut); // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: @@ -2811,6 +2925,8 @@ var b: Boolean; //p: Pointer; Trig: TTrigger; + mapIndex: Integer; + //tw: TStrTextWriter; begin if Mem = nil then Exit; @@ -2820,20 +2936,21 @@ begin // Êîëè÷åñòâî òðèããåðîâ: Mem.ReadInt(count); - if count = 0 then - Exit; + if (count = 0) then exit; for a := 0 to count-1 do begin // Ñèãíàòóðà òðèããåðà: Mem.ReadDWORD(dw); - if dw <> TRIGGER_SIGNATURE then // 'TRGR' + if (dw <> TRIGGER_SIGNATURE) then // 'TRGX' begin raise EBinSizeError.Create('g_Triggers_LoadState: Wrong Trigger Signature'); end; // Òèï òðèããåðà: Mem.ReadByte(Trig.TriggerType); - // Ñïåöèàëüíûå äàííûå òðèããåðà: + // Ñïåöèàëüíûå äàííûå òðèããåðà: èíäåêñ â gCurrentMap.field['triggers'] + if (Trig.TriggerType = TRIGGER_NONE) then continue; // empty one + Mem.ReadInt(mapIndex); //!!!FIXME!!! { Mem.ReadMemory(p, dw); @@ -2844,7 +2961,19 @@ begin Trig.Data := TTriggerData(p^); } // Ñîçäàåì òðèããåð: - i := g_Triggers_Create(Trig); + i := g_Triggers_CreateWithMapIndex(Trig, a, mapIndex); + { + if (gTriggers[i].trigData <> nil) then + begin + tw := TStrTextWriter.Create(); + try + gTriggers[i].trigData.writeTo(tw); + e_LogWritefln('=== trigger #%s loaded ==='#10'%s'#10'---', [mapIndex, tw.str]); + finally + tw.Free(); + end; + end; + } // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà: Mem.ReadInt(gTriggers[i].X); Mem.ReadInt(gTriggers[i].Y); @@ -2858,9 +2987,11 @@ begin // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè: Mem.ReadByte(gTriggers[i].Keys); // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ: - Mem.ReadInt(gTriggers[i].TexturePanel); + Mem.ReadInt(gTriggers[i].TexturePanelGUID); // Òèï ýòîé ïàíåëè: Mem.ReadWord(gTriggers[i].TexturePanelType); + // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû) + Mem.ReadInt(gTriggers[i].trigPanelGUID); // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè: Mem.ReadWord(gTriggers[i].TimeOut); // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: