index 278e92a8c609e42e7af63ffea6cd3e7bf1b1672c..3a1bec2ccbf37a95c84c49de76b6da6bc45c10c0 100644 (file)
--- a/src/game/g_triggers.pas
+++ b/src/game/g_triggers.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
-{$INCLUDE g_amodes.inc}
+{$INCLUDE ../shared/a_modes.inc}
unit g_triggers;
interface
uses
unit g_triggers;
interface
uses
- MAPSTRUCT, e_graphics, MAPDEF, g_basic, g_sound,
- BinEditor;
+ SysUtils, Variants, Classes,
+ MAPDEF, e_graphics, g_basic, g_sound,
+ xdynrec, hashtable, exoma;
type
TActivator = record
UID: Word;
TimeOut: Word;
end;
type
TActivator = record
UID: Word;
TimeOut: Word;
end;
+
+ PTrigger = ^TTrigger;
TTrigger = record
TTrigger = record
+ public
ID: DWORD;
ClientID: DWORD;
TriggerType: Byte;
ID: DWORD;
ClientID: DWORD;
TriggerType: Byte;
Enabled: Boolean;
ActivateType: Byte;
Keys: Byte;
Enabled: Boolean;
ActivateType: Byte;
Keys: Byte;
- TexturePanel: Integer;
- TexturePanelType: Word;
+ TexturePanelGUID: Integer;
+ //TexturePanelType: Word;
TimeOut: Word;
ActivateUID: Word;
TimeOut: Word;
ActivateUID: Word;
AutoSpawn: Boolean;
SpawnCooldown: Integer;
SpawnedCount: Integer;
AutoSpawn: Boolean;
SpawnCooldown: Integer;
SpawnedCount: Integer;
- ShotPanelType: Word;
+ //ShotPanelType: Word;
ShotPanelTime: Integer;
ShotSightTime: Integer;
ShotSightTimeout: Integer;
ShotPanelTime: Integer;
ShotSightTime: Integer;
ShotSightTimeout: Integer;
ShotAmmoCount: Word;
ShotReloadTime: Integer;
ShotAmmoCount: Word;
ShotReloadTime: Integer;
- Data: TTriggerData;
+ mapId: AnsiString; // trigger id, from map
+ mapIndex: Integer; // index in fields['trigger'], used in save/load
+ trigPanelGUID: Integer;
+
+ trigDataRec: TDynRecord; // triggerdata; owned by trigger (cloned)
+ exoInit, exoThink, exoCheck, exoAction: TExprBase;
+
+ userVars: THashStrVariant;
+
+ {$INCLUDE ../shared/mapdef_tgc_def.inc}
+
+ public
+ function trigCenter (): TDFPoint; inline;
end;
end;
-function g_Triggers_Create(Trigger: TTrigger): DWORD;
+function g_Triggers_Create (aTrigger: TTrigger; trec: TDynRecord; 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;
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;
procedure g_Triggers_OpenAll();
procedure g_Triggers_DecreaseSpawner(ID: DWORD);
procedure g_Triggers_Free();
procedure g_Triggers_OpenAll();
procedure g_Triggers_DecreaseSpawner(ID: DWORD);
procedure g_Triggers_Free();
-procedure g_Triggers_SaveState(var Mem: TBinMemoryWriter);
-procedure g_Triggers_LoadState(var Mem: TBinMemoryReader);
+procedure g_Triggers_SaveState (st: TStream);
+procedure g_Triggers_LoadState (st: TStream);
-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;
var
gTriggerClientID: Integer = 0;
gSecretsCount: Integer = 0;
gMonstersSpawned: array of LongInt = nil;
gSecretsCount: Integer = 0;
gMonstersSpawned: array of LongInt = nil;
+
implementation
uses
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,
g_console, g_monsters, g_items, g_phys, g_weapons,
- wadreader, g_main, SysUtils, e_log, g_language,
- g_options, g_net, g_netmsg;
+ wadreader, g_main, e_log, g_language, e_res,
+ g_options, g_net, g_netmsg, utils, xparser, xstreams;
const
const
- TRIGGER_SIGNATURE = $52475254; // 'TRGR'
+ TRIGGER_SIGNATURE = $58475254; // 'TRGX'
TRAP_DAMAGE = 1000;
TRAP_DAMAGE = 1000;
-function FindTrigger(): DWORD;
+{$INCLUDE ../shared/mapdef_tgc_impl.inc}
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+type
+ TTrigScope = class(TExprScope)
+ private
+ plrprops: TPropHash;
+ monsprops: TPropHash;
+ platprops: TPropHash;
+
+ public
+ me: PTrigger;
+
+ public
+ constructor Create ();
+ destructor Destroy (); override;
+
+ function getObj (const aname: AnsiString): TObject; override;
+ function getField (obj: TObject; const afldname: AnsiString): Variant; override;
+ procedure setField (obj: TObject; const afldname: AnsiString; var aval: Variant); override;
+ end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+type
+ TMyConstList = class(TExprConstList)
+ public
+ function valid (const cname: AnsiString): Boolean; override;
+ function get (const cname: AnsiString; out v: Variant): Boolean; override;
+ end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function TMyConstList.valid (const cname: AnsiString): Boolean;
+begin
+ //writeln('CHECK: ''', cname, '''');
+ result :=
+ (cname = 'player') or
+ (cname = 'self') or
+ false;
+end;
+
+function TMyConstList.get (const cname: AnsiString; out v: Variant): Boolean;
var
var
- i: Integer;
+ eidx: Integer;
+ ebs: TDynEBS;
+begin
+ //if (cname = 'answer') then begin v := LongInt(42); result := true; exit; end;
+ result := false;
+ if (gCurrentMap = nil) then exit;
+ for eidx := 0 to gCurrentMap.mapdef.ebsTypeCount-1 do
+ begin
+ ebs := gCurrentMap.mapdef.ebsTypeAt[eidx];
+ if ebs.has[cname] then
+ begin
+ //writeln('FOUND: ''', cname, '''');
+ v := ebs[cname];
+ result := true;
+ exit;
+ end;
+ end;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TTrigScope.Create ();
+begin
+ plrprops := TPropHash.Create(TPlayer, 'e');
+ monsprops := TPropHash.Create(TMonster, 'e');
+ platprops := TPropHash.Create(TPanel, 'e');
+ me := nil;
+end;
+
+
+destructor TTrigScope.Destroy ();
+begin
+ platprops.Free();
+ monsprops.Free();
+ plrprops.Free();
+ inherited;
+end;
+
+
+function TTrigScope.getObj (const aname: AnsiString): TObject;
+begin
+ if (aname = 'player') then result := gPlayers[0] //FIXME
+ else if (aname = 'self') or (aname = 'this') then result := TObject(Pointer(PtrUInt(1)))
+ else result := inherited getObj(aname);
+end;
+
+
+function TTrigScope.getField (obj: TObject; const afldname: AnsiString): Variant;
+begin
+ if (obj = gPlayers[0]) then
+ begin
+ if plrprops.get(obj, afldname, result) then exit;
+ end
+ else if (obj = TObject(Pointer(PtrUInt(1)))) then
+ begin
+ if (me <> nil) and (me.userVars <> nil) then
+ begin
+ if me.userVars.get(afldname, result) then exit;
+ end;
+ end;
+ result := inherited getField(obj, afldname);
+end;
+
+
+procedure TTrigScope.setField (obj: TObject; const afldname: AnsiString; var aval: Variant);
begin
begin
- if gTriggers <> nil then
- for i := 0 to High(gTriggers) do
- if gTriggers[i].TriggerType = TRIGGER_NONE then
+ if (obj = gPlayers[0]) then
+ begin
+ if plrprops.put(obj, afldname, aval) then exit;
+ end
+ else if (obj = TObject(Pointer(PtrUInt(1)))) then
+ begin
+ if (me <> nil) then
+ begin
+ if (Length(afldname) > 4) and (afldname[1] = 'u') and (afldname[2] = 's') and
+ (afldname[3] = 'e') and (afldname[4] = 'r') then
begin
begin
- Result := i;
- Exit;
+ if (me.userVars = nil) then me.userVars := THashStrVariant.Create();
+ me.userVars.put(afldname, aval);
+ exit;
end;
end;
+ end;
+ end;
+ inherited setField(obj, afldname, aval);
+end;
- if gTriggers = nil then
+
+// ////////////////////////////////////////////////////////////////////////// //
+var
+ tgscope: TTrigScope = nil;
+ tgclist: TMyConstList = nil;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function TTrigger.trigCenter (): TDFPoint; inline;
+begin
+ result := TDFPoint.Create(x+width div 2, y+height div 2);
+end;
+
+
+function FindTrigger (): DWORD;
+var
+ i, olen: Integer;
+begin
+ olen := Length(gTriggers);
+
+ for i := 0 to olen-1 do
begin
begin
- SetLength(gTriggers, 8);
- Result := 0;
- end
- else
+ if gTriggers[i].TriggerType = TRIGGER_NONE then begin result := i; exit; end;
+ end;
+
+ SetLength(gTriggers, olen+8);
+ result := olen;
+
+ for i := result to High(gTriggers) do
begin
begin
- Result := High(gTriggers) + 1;
- SetLength(gTriggers, Length(gTriggers) + 8);
+ gTriggers[i].TriggerType := TRIGGER_NONE;
+ gTriggers[i].trigDataRec := nil;
+ gTriggers[i].exoInit := nil;
+ gTriggers[i].exoThink := nil;
+ gTriggers[i].exoCheck := nil;
+ gTriggers[i].exoAction := nil;
+ gTriggers[i].userVars := nil;
end;
end;
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;
var
a, b, c: Integer;
+ pan: TPanel;
+ PanelID: Integer;
begin
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 not d2d then
begin
with gWalls[PanelID] do
begin
- if g_CollidePlayer(X, Y, Width, Height) or
- g_CollideMonster(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 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;
end;
- g_Map_EnableWall(PanelID);
- Result := True;
+ g_Map_EnableWallGUID(PanelGUID);
+ result := true;
end;
end;
end
else
begin
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
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;
if gDoorMap[a, b] = DWORD(PanelID) then
begin
c := a;
- Break;
+ break;
end;
end;
-
- if c <> -1 then Break;
+ end;
+ if (c <> -1) then break;
end;
end;
- if c = -1 then Exit;
+ if (c = -1) then exit;
for b := 0 to High(gDoorMap[c]) do
for b := 0 to High(gDoorMap[c]) do
+ begin
with gWalls[gDoorMap[c, b]] do
begin
with gWalls[gDoorMap[c, b]] do
begin
- if g_CollidePlayer(X, Y, Width, Height) or
- g_CollideMonster(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;
+ end;
if not NoSound then
if not NoSound then
+ begin
for b := 0 to High(gDoorMap[c]) do
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 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;
end;
- Break;
+ break;
end;
end;
+ end;
+ end;
for b := 0 to High(gDoorMap[c]) do
for b := 0 to High(gDoorMap[c]) do
+ begin
if not gWalls[gDoorMap[c, b]].Enabled then
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;
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;
var
a, b, c: Integer;
+ wx, wy, wh, ww: Integer;
+ pan: TPanel;
+ PanelID: Integer;
+
+ function monsDamage (mon: TMonster): Boolean;
+ begin
+ result := false; // don't stop
+ if g_Obj_Collide(wx, wy, ww, wh, @mon.Obj) then mon.Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
+ end;
+
begin
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
with gWalls[PanelID] do
if not d2d then
begin
with gWalls[PanelID] do
+ begin
if (not NoSound) and (not Enabled) then
begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH1', X, Y);
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;
+ end;
+
+ wx := gWalls[PanelID].X;
+ wy := gWalls[PanelID].Y;
+ ww := gWalls[PanelID].Width;
+ wh := gWalls[PanelID].Height;
with gWalls[PanelID] do
begin
if gPlayers <> nil then
with gWalls[PanelID] do
begin
if gPlayers <> nil then
+ begin
for a := 0 to High(gPlayers) do
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);
gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
+ end;
+ end;
+ end;
- if gMonsters <> nil then
- for a := 0 to High(gMonsters) do
- if (gMonsters[a] <> nil) and gMonsters[a].Live and
- g_Obj_Collide(X, Y, Width, Height, @gMonsters[a].Obj) then
- gMonsters[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
+ //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
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
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;
if gDoorMap[a, b] = DWORD(PanelID) then
begin
c := a;
- Break;
+ break;
end;
end;
-
- if c <> -1 then Break;
+ end;
+ if (c <> -1) then break;
end;
end;
- if c = -1 then Exit;
+ if (c = -1) then exit;
if not NoSound then
if not NoSound then
+ begin
for b := 0 to High(gDoorMap[c]) do
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_SWITCH1', X, Y);
if not gWalls[gDoorMap[c, b]].Enabled then
begin
with gWalls[PanelID] do
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;
Break;
end;
end;
Break;
end;
+ end;
+ end;
for b := 0 to High(gDoorMap[c]) do
for b := 0 to High(gDoorMap[c]) do
+ begin
+ wx := gWalls[gDoorMap[c, b]].X;
+ wy := gWalls[gDoorMap[c, b]].Y;
+ ww := gWalls[gDoorMap[c, b]].Width;
+ wh := gWalls[gDoorMap[c, b]].Height;
+
with gWalls[gDoorMap[c, b]] do
begin
if gPlayers <> nil then
with gWalls[gDoorMap[c, b]] do
begin
if gPlayers <> nil then
+ begin
for a := 0 to High(gPlayers) do
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);
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 <> 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);
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;
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;
var
a, b, c: Integer;
+ pan: TPanel;
+ PanelID: Integer;
begin
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
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 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;
end;
- g_Map_DisableWall(PanelID);
- Result := True;
+ g_Map_DisableWallGUID(PanelGUID);
+ result := true;
end;
end;
+ end
end
else
begin
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
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;
if gDoorMap[a, b] = DWORD(PanelID) then
begin
c := a;
- Break;
+ break;
end;
end;
-
- if c <> -1 then Break;
+ end;
+ if (c <> -1) then break;
end;
end;
- if c = -1 then Exit;
+ if (c = -1) then exit;
if not NoSound then
if not NoSound then
+ begin
for b := 0 to High(gDoorMap[c]) do
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 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;
end;
- Break;
+ break;
end;
end;
+ end;
+ end;
for b := 0 to High(gDoorMap[c]) do
for b := 0 to High(gDoorMap[c]) do
+ begin
if gWalls[gDoorMap[c, b]].Enabled then
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;
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
var
- a, b, c, t: Integer;
+ a, b, c: Integer;
+ t: Integer = 0;
+ pan: TPanel;
+ PanelID: Integer;
begin
begin
- t := 0;
- Result := False;
+ result := false;
+ pan := g_Map_PanelByGUID(PanelGUID);
+ if (pan = nil) or not pan.isGLift then exit; //!FIXME!TRIGANY!
+ PanelID := pan.arrIdx;
- if PanelID = -1 then Exit;
-
- 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
case d of
- 0: t := 0;
- 1: t := 1;
- else t := IfThen(gLifts[PanelID].LiftType = 1, 0, 1);
+ 0: t := LIFTTYPE_UP;
+ 1: t := LIFTTYPE_DOWN;
+ else t := IfThen(gLifts[PanelID].LiftType = LIFTTYPE_DOWN, LIFTTYPE_UP, LIFTTYPE_DOWN);
end
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
case d of
- 0: t := 2;
- 1: t := 3;
- else t := IfThen(gLifts[PanelID].LiftType = 2, 3, 2);
+ 0: t := LIFTTYPE_LEFT;
+ 1: t := LIFTTYPE_RIGHT;
+ else t := IfThen(gLifts[PanelID].LiftType = LIFTTYPE_LEFT, LIFTTYPE_RIGHT, LIFTTYPE_LEFT);
end;
end;
+ end;
if not d2d then
begin
with gLifts[PanelID] do
if not d2d then
begin
with gLifts[PanelID] do
- if LiftType <> t then
+ begin
+ if (LiftType <> t) then
begin
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;
end
else // Êàê â D2d
begin
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
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;
begin
c := a;
- Break;
+ break;
end;
end;
-
- if c <> -1 then Break;
+ end;
+ if (c <> -1) then break;
end;
end;
- if c = -1 then Exit;
+ if (c = -1) then exit;
{if not NoSound then
for b := 0 to High(gLiftMap[c]) do
{if not NoSound then
for b := 0 to High(gLiftMap[c]) do
end;}
for b := 0 to High(gLiftMap[c]) do
end;}
for b := 0 to High(gLiftMap[c]) do
+ begin
with gLifts[gLiftMap[c, b]] do
with gLifts[gLiftMap[c, b]] do
- if LiftType <> t then
+ begin
+ if (LiftType <> t) then
begin
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;
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
var
snd: string;
Projectile: Boolean;
TextureID: DWORD;
Anim: TAnimation;
begin
- Result := -1;
+ result := -1;
TextureID := DWORD(-1);
snd := 'SOUND_WEAPON_FIREROCKET';
TextureID := DWORD(-1);
snd := 'SOUND_WEAPON_FIREROCKET';
- Projectile := True;
+ Projectile := true;
+
case ShotType of
TRIGGER_SHOT_PISTOL:
begin
case ShotType of
TRIGGER_SHOT_PISTOL:
begin
if ShotSound then
begin
g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET);
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;
end;
end;
if ShotSound then
begin
g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET);
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;
end;
end;
if ShotSound then
begin
g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
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;
end;
end;
begin
g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
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;
TRIGGER_SHOT_IMP:
begin
end;
end;
TRIGGER_SHOT_IMP:
begin
- g_Weapon_ball1(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_ball1(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_PLASMA:
begin
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_PLASMA:
begin
- g_Weapon_Plasma(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_Plasma(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREPLASMA';
end;
TRIGGER_SHOT_SPIDER:
begin
snd := 'SOUND_WEAPON_FIREPLASMA';
end;
TRIGGER_SHOT_SPIDER:
begin
- g_Weapon_aplasma(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_aplasma(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREPLASMA';
end;
TRIGGER_SHOT_CACO:
begin
snd := 'SOUND_WEAPON_FIREPLASMA';
end;
TRIGGER_SHOT_CACO:
begin
- g_Weapon_ball2(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_ball2(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_BARON:
begin
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_BARON:
begin
- g_Weapon_ball7(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_ball7(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_MANCUB:
begin
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_MANCUB:
begin
- g_Weapon_manfire(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_manfire(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREBALL';
end;
snd := 'SOUND_WEAPON_FIREBALL';
end;
TRIGGER_SHOT_ROCKET:
begin
TRIGGER_SHOT_ROCKET:
begin
- g_Weapon_Rocket(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_Rocket(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREROCKET';
end;
TRIGGER_SHOT_BFG:
begin
snd := 'SOUND_WEAPON_FIREROCKET';
end;
TRIGGER_SHOT_BFG:
begin
- g_Weapon_BFGShot(wx, wy, dx, dy, 0, -1, True);
+ g_Weapon_BFGShot(wx, wy, dx, dy, 0, -1, True, False);
snd := 'SOUND_WEAPON_FIREBFG';
end;
snd := 'SOUND_WEAPON_FIREBFG';
end;
snd := 'SOUND_WEAPON_EXPLODEBFG';
end;
snd := 'SOUND_WEAPON_EXPLODEBFG';
end;
+ TRIGGER_SHOT_FLAME:
+ begin
+ g_Weapon_flame(wx, wy, dx, dy, 0, -1, True, False);
+ snd := 'SOUND_GAME_BURNING';
+ end;
+
else exit;
end;
if g_Game_IsNet and g_Game_IsServer then
else exit;
end;
if g_Game_IsNet and g_Game_IsServer then
+ begin
case ShotType of
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
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;
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;
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
begin
with Trigger do
- if (Data.ShotAmmo = 0) or
- ((Data.ShotAmmo > 0) and (ShotAmmoCount > 0)) then
+ begin
+ if (tgcAmmo = 0) or ((tgcAmmo > 0) and (ShotAmmoCount > 0)) then
begin
begin
- if (Data.ShotPanelID <> -1) and (ShotPanelTime = 0) then
+ if (trigPanelGUID <> -1) and (ShotPanelTime = 0) then
begin
begin
- g_Map_SwitchTexture(ShotPanelType, Data.ShotPanelID);
+ g_Map_SwitchTextureGUID({ShotPanelType,} trigPanelGUID);
ShotPanelTime := 4; // òèêîâ íà âñïûøêó âûñòðåëà
end;
ShotPanelTime := 4; // òèêîâ íà âñïûøêó âûñòðåëà
end;
- if Data.ShotIntSight > 0 then
- ShotSightTimeout := 180; // ~= 5 ñåêóíä
+ if (tgcSight > 0) then ShotSightTimeout := 180; // ~= 5 ñåêóíä
- if ShotAmmoCount > 0 then Dec(ShotAmmoCount);
+ if (ShotAmmoCount > 0) then Dec(ShotAmmoCount);
- dx := dx + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
- dy := dy + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
-
- tr_SpawnShot(Data.ShotType, wx, wy, dx, dy, Data.ShotSound, TargetUID);
+ dx += Random(tgcAccuracy)-Random(tgcAccuracy);
+ dy += Random(tgcAccuracy)-Random(tgcAccuracy);
+
+ tr_SpawnShot(tgcShotType, wx, wy, dx, dy, tgcShotSound, TargetUID);
end
else
end
else
- if (Data.ShotIntReload > 0) and (ShotReloadTime = 0) then
- ShotReloadTime := Data.ShotIntReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè
+ begin
+ if (tgcReload > 0) and (ShotReloadTime = 0) then
+ begin
+ ShotReloadTime := tgcReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè
+ end;
+ 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
var
FramesID: DWORD;
Anim: TAnimation;
begin
if T = TRIGGER_EFFECT_PARTICLE then
+ begin
case ST of
TRIGGER_EFFECT_SLIQUID:
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);
- 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);
+ 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_Game_Effect_Bubbles(X, Y, 1, 0, 0, Silent);
end;
end;
+ end;
+
if T = TRIGGER_EFFECT_ANIMATION then
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);
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;
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);
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;
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);
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;
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;
+ 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;
var
p: TPlayer;
m: TMonster;
UID_PLAYER:
begin
p := g_Player_Get(ActivateUID);
UID_PLAYER:
begin
p := g_Player_Get(ActivateUID);
- if p = nil then
- Exit;
-
+ if p = nil then Exit;
if D2D then
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
else
- if p.TeleportTo(TX, TY, Silent, TDir) then
- Result := True;
+ begin
+ if p.TeleportTo(TX, TY, Silent, TDir) then result := true;
+ end;
end;
end;
-
UID_MONSTER:
begin
UID_MONSTER:
begin
- m := g_Monsters_Get(ActivateUID);
- if m = nil then
- Exit;
-
+ m := g_Monsters_ByUID(ActivateUID);
+ if m = nil then Exit;
if D2D then
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
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;
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
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);
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
if ResetVel then
begin
UID_MONSTER:
begin
UID_MONSTER:
begin
- m := g_Monsters_Get(ActivateUID);
- if m = nil then
- Exit;
+ m := g_Monsters_ByUID(ActivateUID);
+ if m = nil then Exit;
if ResetVel then
begin
if ResetVel then
begin
end;
end;
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;
var
msg: string;
p: TPlayer;
if (ActivateUID < 0) or (ActivateUID > $FFFF) then Exit;
msg := b_Text_Format(MText);
case MSendTo of
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
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
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;
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
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
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 (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;
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
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
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 (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;
end;
end;
end;
- 3: // red team
+ TRIGGER_MESSAGE_DEST_RED_TEAM: // red team
begin
if g_Game_IsWatchedTeam(TEAM_RED) then
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
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 (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;
end;
end;
- 4: // blue team
+ TRIGGER_MESSAGE_DEST_BLUE_TEAM: // blue team
begin
if g_Game_IsWatchedTeam(TEAM_BLUE) then
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
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 (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;
end;
end;
- 5: // everyone
+ TRIGGER_MESSAGE_DEST_EVERYONE: // everyone
begin
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 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;
end;
end;
end;
end;
-function tr_ShotAimCheck(var Trigger: TTrigger; Obj: PObj): Boolean;
+
+function tr_ShotAimCheck (var Trigger: TTrigger; Obj: PObj): Boolean;
begin
begin
+ result := false;
with Trigger do
begin
with Trigger do
begin
- if TriggerType <> TRIGGER_SHOT then
- Exit;
- Result := (Data.ShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
+ if TriggerType <> TRIGGER_SHOT then Exit;
+ result := (tgcAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
or g_Obj_Collide(X, Y, Width, Height, Obj);
or g_Obj_Collide(X, Y, Width, Height, Obj);
- if Result and (Data.ShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
- Result := g_TraceVector(Data.ShotPos.X,
- Data.ShotPos.Y,
+ if result and (tgcAim and TRIGGER_SHOT_AIM_TRACE > 0) then
+ begin
+ result := g_TraceVector(tgcTX, tgcTY,
Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2),
Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2));
Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2),
Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2));
+ end;
end;
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;
var
animonce: Boolean;
p: TPlayer;
m: TMonster;
- i, k, wx, wy, xd, yd: Integer;
+ pan: TPanel;
+ idx, k, wx, wy, xd, yd: Integer;
iid: LongWord;
coolDown: Boolean;
pAngle: Real;
iid: LongWord;
coolDown: Boolean;
pAngle: Real;
Anim: TAnimation;
UIDType: Byte;
TargetUID: Word;
Anim: TAnimation;
UIDType: Byte;
TargetUID: Word;
+ it: PItem;
+ mon: TMonster;
+
+ function monsShotTarget (mon: TMonster): Boolean;
+ begin
+ result := false; // don't stop
+ 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;
+ TargetUID := mon.UID;
+ result := true; // stop
+ end;
+ end;
+
+ function monsShotTargetMonPlr (mon: TMonster): Boolean;
+ begin
+ result := false; // don't stop
+ 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;
+ TargetUID := mon.UID;
+ result := true; // stop
+ end;
+ end;
+
+ function monShotTargetPlrMon (mon: TMonster): Boolean;
+ begin
+ result := false; // don't stop
+ 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;
+ TargetUID := mon.UID;
+ result := true; // stop
+ end;
+ end;
+
+var
+ tvval: Variant;
begin
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_NONE) then exit;
+
+ if (Trigger.exoCheck <> nil) then
+ begin
+ //conwritefln('exocheck: [%s]', [Trigger.exoCheck.toString()]);
+ try
+ tgscope.me := @Trigger;
+ tvval := Trigger.exoCheck.value(tgscope);
+ tgscope.me := nil;
+ if not Boolean(tvval) then exit;
+ except on e: Exception do
+ begin
+ tgscope.me := nil;
+ conwritefln('trigger exocheck error: %s [%s]', [e.message, Trigger.exoCheck.toString()]);
+ exit;
+ end;
+ end;
+ end;
animonce := False;
coolDown := (actType <> 0);
animonce := False;
coolDown := (actType <> 0);
+ if (Trigger.exoAction <> nil) then
+ begin
+ //conwritefln('exoactivate: [%s]', [Trigger.exoAction.toString()]);
+ try
+ tgscope.me := @Trigger;
+ Trigger.exoAction.value(tgscope);
+ tgscope.me := nil;
+ except on e: Exception do
+ begin
+ tgscope.me := nil;
+ conwritefln('trigger exoactivate error: %s [%s]', [e.message, Trigger.exoAction.toString()]);
+ exit;
+ end;
+ end;
+ end;
+
with Trigger do
begin
case TriggerType of
with Trigger do
begin
case TriggerType of
g_Sound_PlayEx('SOUND_GAME_SWITCH0');
if g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH0');
gExitByTrigger := True;
g_Sound_PlayEx('SOUND_GAME_SWITCH0');
if g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH0');
gExitByTrigger := True;
- g_Game_ExitLevel(Data.MapName);
+ g_Game_ExitLevel(tgcMap);
TimeOut := 18;
Result := True;
TimeOut := 18;
Result := True;
TRIGGER_TELEPORT:
begin
Result := tr_Teleport(ActivateUID,
TRIGGER_TELEPORT:
begin
Result := tr_Teleport(ActivateUID,
- Data.TargetPoint.X, Data.TargetPoint.Y,
- Data.TlpDir, Data.silent_teleport,
- Data.d2d_teleport);
+ tgcTarget.X, tgcTarget.Y,
+ tgcDirection, tgcSilent,
+ tgcD2d);
TimeOut := 0;
end;
TRIGGER_OPENDOOR:
begin
TimeOut := 0;
end;
TRIGGER_OPENDOOR:
begin
- Result := tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_OpenDoor(trigPanelGUID, tgcSilent, tgcD2d);
TimeOut := 0;
end;
TRIGGER_CLOSEDOOR:
begin
TimeOut := 0;
end;
TRIGGER_CLOSEDOOR:
begin
- Result := tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_CloseDoor(trigPanelGUID, tgcSilent, tgcD2d);
TimeOut := 0;
end;
TRIGGER_DOOR, TRIGGER_DOOR5:
begin
TimeOut := 0;
end;
TRIGGER_DOOR, TRIGGER_DOOR5:
begin
- if Data.PanelID <> -1 then
+ pan := g_Map_PanelByGUID(trigPanelGUID);
+ if (pan <> nil) and pan.isGWall then
begin
begin
- if gWalls[Data.PanelID].Enabled then
- begin
- Result := tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
-
- if TriggerType = TRIGGER_DOOR5 then
- DoorTime := 180;
- end
+ if gWalls[{trigPanelID}pan.arrIdx].Enabled then
+ begin
+ result := tr_OpenDoor(trigPanelGUID, tgcSilent, tgcD2d);
+ if (TriggerType = TRIGGER_DOOR5) then DoorTime := 180;
+ end
else
else
- Result := tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ begin
+ result := tr_CloseDoor(trigPanelGUID, tgcSilent, tgcD2d);
+ end;
- if Result then
- TimeOut := 18;
+ if result then TimeOut := 18;
end;
end;
TRIGGER_CLOSETRAP, TRIGGER_TRAP:
begin
end;
end;
TRIGGER_CLOSETRAP, TRIGGER_TRAP:
begin
- tr_CloseTrap(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ tr_CloseTrap(trigPanelGUID, tgcSilent, tgcD2d);
if TriggerType = TRIGGER_TRAP then
begin
if TriggerType = TRIGGER_TRAP then
begin
TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF:
begin
TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF:
begin
- PressCount := PressCount + 1;
-
- if PressTime = -1 then
- PressTime := Data.Wait;
-
- if coolDown then
- TimeOut := 18
- else
- TimeOut := 0;
+ PressCount += 1;
+ if PressTime = -1 then PressTime := tgcWait;
+ if coolDown then TimeOut := 18 else TimeOut := 0;
Result := True;
end;
Result := True;
end;
begin
Enabled := False;
Result := True;
begin
Enabled := False;
Result := True;
- if gLMSRespawn = LMS_RESPAWN_NONE then
+ p := g_Player_Get(ActivateUID);
+ p.GetSecret();
+ Inc(gCoopSecretsFound);
+ if g_Game_IsNet then
begin
begin
- g_Player_Get(ActivateUID).GetSecret();
- Inc(gCoopSecretsFound);
- if g_Game_IsNet then MH_SEND_GameStats();
+ MH_SEND_GameStats();
+ MH_SEND_GameEvent(NET_EV_SECRET, p.UID, '');
end;
end;
TRIGGER_LIFTUP:
begin
end;
end;
TRIGGER_LIFTUP:
begin
- Result := tr_SetLift(Data.PanelID, 0, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelGUID, 0, tgcSilent, tgcD2d);
TimeOut := 0;
TimeOut := 0;
- if (not Data.NoSound) and Result then begin
+ if (not tgcSilent) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_LIFTDOWN:
begin
TRIGGER_LIFTDOWN:
begin
- Result := tr_SetLift(Data.PanelID, 1, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelGUID, 1, tgcSilent, tgcD2d);
TimeOut := 0;
TimeOut := 0;
- if (not Data.NoSound) and Result then begin
+ if (not tgcSilent) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_LIFT:
begin
TRIGGER_LIFT:
begin
- Result := tr_SetLift(Data.PanelID, 3, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelGUID, 3, tgcSilent, tgcD2d);
if Result then
begin
TimeOut := 18;
if Result then
begin
TimeOut := 18;
- if (not Data.NoSound) and Result then begin
+ if (not tgcSilent) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_TEXTURE:
begin
TRIGGER_TEXTURE:
begin
- if ByteBool(Data.ActivateOnce) then
+ if tgcActivateOnce then
begin
Enabled := False;
TriggerType := TRIGGER_NONE;
begin
Enabled := False;
TriggerType := TRIGGER_NONE;
else
TimeOut := 0;
else
TimeOut := 0;
- animonce := Data.AnimOnce;
+ animonce := tgcAnimateOnce;
Result := True;
end;
Result := True;
end;
begin
if Sound <> nil then
begin
begin
if Sound <> nil then
begin
- if Data.SoundSwitch and Sound.IsPlaying() then
+ if tgcSoundSwitch and Sound.IsPlaying() then
begin // Íóæíî âûêëþ÷èòü, åñëè èãðàë
Sound.Stop();
SoundPlayCount := 0;
Result := True;
end
else // (not Data.SoundSwitch) or (not Sound.IsPlaying())
begin // Íóæíî âûêëþ÷èòü, åñëè èãðàë
Sound.Stop();
SoundPlayCount := 0;
Result := True;
end
else // (not Data.SoundSwitch) or (not Sound.IsPlaying())
- if (Data.PlayCount > 0) or (not Sound.IsPlaying()) then
+ if (tgcPlayCount > 0) or (not Sound.IsPlaying()) then
begin
begin
- if Data.PlayCount > 0 then
- SoundPlayCount := Data.PlayCount
+ if tgcPlayCount > 0 then
+ SoundPlayCount := tgcPlayCount
else // 0 - èãðàåì áåñêîíå÷íî
SoundPlayCount := 1;
Result := True;
else // 0 - èãðàåì áåñêîíå÷íî
SoundPlayCount := 1;
Result := True;
end;
TRIGGER_SPAWNMONSTER:
end;
TRIGGER_SPAWNMONSTER:
- if (Data.MonType in [MONSTER_DEMON..MONSTER_MAN]) then
+ if (tgcSpawnMonsType in [MONSTER_DEMON..MONSTER_MAN]) then
begin
Result := False;
begin
Result := False;
- if (Data.MonDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
+ if (tgcDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
Result := True;
end;
Result := True;
end;
- if ((Data.MonDelay = 0) and (actType <> ACTIVATE_CUSTOM))
- or ((Data.MonDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
- for k := 1 to Data.MonCount do
+ if ((tgcDelay = 0) and (actType <> ACTIVATE_CUSTOM))
+ or ((tgcDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
+ for k := 1 to tgcMonsCount do
begin
begin
- if (actType = ACTIVATE_CUSTOM) and (Data.MonDelay > 0) then
- SpawnCooldown := Data.MonDelay;
- if (Data.MonMax > 0) and (SpawnedCount >= Data.MonMax) then
+ if (actType = ACTIVATE_CUSTOM) and (tgcDelay > 0) then
+ SpawnCooldown := -1; // Çàäåðæêà âûñòàâèòñÿ ìîíñòðîì ïðè óíè÷òîæåíèè
+ if (tgcMax > 0) and (SpawnedCount >= tgcMax) then
Break;
Break;
- i := g_Monsters_Create(Data.MonType,
- Data.MonPos.X, Data.MonPos.Y,
- TDirection(Data.MonDir), True);
+ mon := g_Monsters_Create(tgcSpawnMonsType,
+ tgcTX, tgcTY,
+ TDirection(tgcDirection), True);
Result := True;
// Çäîðîâüå:
Result := True;
// Çäîðîâüå:
- if (Data.MonHealth > 0) then
- gMonsters[i].SetHealth(Data.MonHealth);
+ if (tgcHealth > 0) then
+ mon.SetHealth(tgcHealth);
// Óñòàíàâëèâàåì ïîâåäåíèå:
// Óñòàíàâëèâàåì ïîâåäåíèå:
- gMonsters[i].MonsterBehaviour := Data.MonBehav;
- gMonsters[i].FNoRespawn := True;
+ mon.MonsterBehaviour := tgcBehaviour;
+ mon.FNoRespawn := True;
if g_Game_IsNet then
if g_Game_IsNet then
- MH_SEND_MonsterSpawn(gMonsters[i].UID);
+ MH_SEND_MonsterSpawn(mon.UID);
// Èäåì èñêàòü öåëü, åñëè íàäî:
// Èäåì èñêàòü öåëü, åñëè íàäî:
- if Data.MonActive then
- gMonsters[i].WakeUp();
+ if tgcActive then
+ mon.WakeUp();
- if Data.MonType <> MONSTER_BARREL then Inc(gTotalMonsters);
+ if tgcSpawnMonsType <> MONSTER_BARREL then Inc(gTotalMonsters);
if g_Game_IsNet then
begin
SetLength(gMonstersSpawned, Length(gMonstersSpawned)+1);
if g_Game_IsNet then
begin
SetLength(gMonstersSpawned, Length(gMonstersSpawned)+1);
- gMonstersSpawned[High(gMonstersSpawned)] := gMonsters[i].UID;
+ gMonstersSpawned[High(gMonstersSpawned)] := mon.UID;
end;
end;
- if Data.MonMax > 0 then
- begin
- gMonsters[i].SpawnTrigger := ID;
- Inc(SpawnedCount);
- end;
+ mon.SpawnTrigger := ID;
+ if tgcMax > 0 then Inc(SpawnedCount);
- case Data.MonEffect of
+ case tgcEffect of
EFFECT_TELEPORT: begin
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
EFFECT_TELEPORT: begin
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
- g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.MonPos.X, Data.MonPos.Y);
- g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-32, Anim);
+ g_Sound_PlayExAt('SOUND_GAME_TELEPORT', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-32, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_TELE);
end;
EFFECT_RESPAWN: begin
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
NET_GFX_TELE);
end;
EFFECT_RESPAWN: begin
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.MonPos.X, Data.MonPos.Y);
- g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-16,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-16, Anim);
+ g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-16,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+(gMonsters[i].Obj.Rect.Height div 2)-16, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_RESPAWN);
end;
EFFECT_FIRE: begin
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
NET_GFX_RESPAWN);
end;
EFFECT_FIRE: begin
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_FIRE', Data.MonPos.X, Data.MonPos.Y);
- g_GFX_OnceAnim(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+gMonsters[i].Obj.Rect.Height-128, Anim);
+ g_Sound_PlayExAt('SOUND_FIRE', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gMonsters[i].Obj.X+gMonsters[i].Obj.Rect.X+(gMonsters[i].Obj.Rect.Width div 2)-32,
- gMonsters[i].Obj.Y+gMonsters[i].Obj.Rect.Y+gMonsters[i].Obj.Rect.Height-128, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_FIRE);
end;
end;
NET_GFX_FIRE);
end;
end;
end;
TRIGGER_SPAWNITEM:
end;
TRIGGER_SPAWNITEM:
- if (Data.ItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then
+ if (tgcSpawnItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then
begin
Result := False;
begin
Result := False;
- if (Data.ItemDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
+ if (tgcDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
Result := True;
end;
Result := True;
end;
- if ((Data.ItemDelay = 0) and (actType <> ACTIVATE_CUSTOM))
- or ((Data.ItemDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
- if (not Data.ItemOnlyDM) or
+ if ((tgcDelay = 0) and (actType <> ACTIVATE_CUSTOM))
+ or ((tgcDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
+ if (not tgcDmonly) or
(gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then
(gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then
- for k := 1 to Data.ItemCount do
+ for k := 1 to tgcItemCount do
begin
begin
- if (actType = ACTIVATE_CUSTOM) and (Data.ItemDelay > 0) then
- SpawnCooldown := Data.ItemDelay;
- if (Data.ItemMax > 0) and (SpawnedCount >= Data.ItemMax) then
+ if (actType = ACTIVATE_CUSTOM) and (tgcDelay > 0) then
+ SpawnCooldown := -1; // Çàäåðæêà âûñòàâèòñÿ èòåìîì ïðè óíè÷òîæåíèè
+ if (tgcMax > 0) and (SpawnedCount >= tgcMax) then
Break;
Break;
- iid := g_Items_Create(Data.ItemPos.X, Data.ItemPos.Y,
- Data.ItemType, Data.ItemFalls, False, True);
+ iid := g_Items_Create(tgcTX, tgcTY,
+ tgcSpawnItemType, tgcGravity, False, True);
Result := True;
Result := True;
- if Data.ItemMax > 0 then
- begin
- gItems[iid].SpawnTrigger := ID;
- Inc(SpawnedCount);
- end;
+ it := g_Items_ByIdx(iid);
+ it.SpawnTrigger := ID;
+ if tgcMax > 0 then Inc(SpawnedCount);
- case Data.ItemEffect of
+ case tgcEffect of
EFFECT_TELEPORT: begin
EFFECT_TELEPORT: begin
+ it := g_Items_ByIdx(iid);
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
- g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.ItemPos.X, Data.ItemPos.Y);
- g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, Anim);
+ g_Sound_PlayExAt('SOUND_GAME_TELEPORT', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_TELE);
end;
EFFECT_RESPAWN: begin
NET_GFX_TELE);
end;
EFFECT_RESPAWN: begin
+ it := g_Items_ByIdx(iid);
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.ItemPos.X, Data.ItemPos.Y);
- g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, Anim);
+ g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_RESPAWN);
end;
EFFECT_FIRE: begin
NET_GFX_RESPAWN);
end;
EFFECT_FIRE: begin
+ it := g_Items_ByIdx(iid);
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_FIRE', Data.ItemPos.X, Data.ItemPos.Y);
- g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, Anim);
+ g_Sound_PlayExAt('SOUND_FIRE', tgcTX, tgcTY);
+ 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();
end;
if g_Game_IsServer and g_Game_IsNet then
Anim.Free();
end;
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
- gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, 1,
+ MH_SEND_Effect(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, 1,
NET_GFX_FIRE);
end;
end;
NET_GFX_FIRE);
end;
end;
TRIGGER_MUSIC:
begin
// Ìåíÿåì ìóçûêó, åñëè åñòü íà ÷òî:
TRIGGER_MUSIC:
begin
// Ìåíÿåì ìóçûêó, åñëè åñòü íà ÷òî:
- if (Trigger.Data.MusicName <> '') then
+ if (Trigger.tgcMusicName <> '') then
begin
begin
- gMusic.SetByName(Trigger.Data.MusicName);
+ gMusic.SetByName(Trigger.tgcMusicName);
gMusic.SpecPause := True;
gMusic.Play();
end;
gMusic.SpecPause := True;
gMusic.Play();
end;
- if Trigger.Data.MusicAction = 1 then
- begin // Âêëþ÷èòü
+ case Trigger.tgcMusicAction of
+ TRIGGER_MUSIC_ACTION_STOP: // Âûêëþ÷èòü
+ gMusic.SpecPause := True; // Ïàóçà
+ TRIGGER_MUSIC_ACTION_PLAY: // Âêëþ÷èòü
if gMusic.SpecPause then // Áûëà íà ïàóçå => èãðàòü
gMusic.SpecPause := False
else // Èãðàëà => ñíà÷àëà
gMusic.SetPosition(0);
if gMusic.SpecPause then // Áûëà íà ïàóçå => èãðàòü
gMusic.SpecPause := False
else // Èãðàëà => ñíà÷àëà
gMusic.SetPosition(0);
- end
- else // Âûêëþ÷èòü
- begin
- // Ïàóçà:
- gMusic.SpecPause := True;
- end;
+ end;
if coolDown then
TimeOut := 36
if coolDown then
TimeOut := 36
TRIGGER_PUSH:
begin
TRIGGER_PUSH:
begin
- pAngle := -DegToRad(Data.PushAngle);
+ pAngle := -DegToRad(tgcAngle);
Result := tr_Push(ActivateUID,
Result := tr_Push(ActivateUID,
- Floor(Cos(pAngle)*Data.PushForce),
- Floor(Sin(pAngle)*Data.PushForce),
- Data.ResetVel);
+ Floor(Cos(pAngle)*tgcForce),
+ Floor(Sin(pAngle)*tgcForce),
+ tgcResetVelocity);
TimeOut := 0;
end;
TimeOut := 0;
end;
begin
Result := False;
// Ïðèáàâèòü èëè îòíÿòü î÷êî
begin
Result := False;
// Ïðèáàâèòü èëè îòíÿòü î÷êî
- if (Data.ScoreAction in [0..1]) and (Data.ScoreCount > 0) then
+ if (tgcScoreAction in [TRIGGER_SCORE_ACTION_ADD, TRIGGER_SCORE_ACTION_SUB]) and (tgcScoreCount > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäå
begin
// Ñâîåé èëè ÷óæîé êîìàíäå
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (tgcScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreAction = 0) and (Data.ScoreTeam = 0) and (p.Team = TEAM_RED))
- or ((Data.ScoreAction = 0) and (Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED))
+ or ((tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then
begin
begin
- Inc(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Scores
+ Inc(gTeamStat[TEAM_RED].Score, tgcScoreCount); // Red Scores
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+r');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '+r');
end else
begin
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+re');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '+re');
end;
end;
+ end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
- if ((Data.ScoreAction = 1) and (Data.ScoreTeam = 0) and (p.Team = TEAM_RED))
- or ((Data.ScoreAction = 1) and (Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED))
+ or ((tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then
begin
begin
- Dec(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Fouls
+ Dec(gTeamStat[TEAM_RED].Score, tgcScoreCount); // Red Fouls
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-r');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '-r');
end else
begin
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-re');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '-re');
end;
end;
+ end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
- if ((Data.ScoreAction = 0) and (Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE))
- or ((Data.ScoreAction = 0) and (Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE))
+ or ((tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then
begin
begin
- Inc(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Scores
+ Inc(gTeamStat[TEAM_BLUE].Score, tgcScoreCount); // Blue Scores
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+b');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '+b');
end else
begin
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+be');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '+be');
end;
end;
+ end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
- if ((Data.ScoreAction = 1) and (Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE))
- or ((Data.ScoreAction = 1) and (Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE))
+ or ((tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then
begin
begin
- Dec(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Fouls
+ Dec(gTeamStat[TEAM_BLUE].Score, tgcScoreCount); // Blue Fouls
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-b');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '-b');
end else
begin
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, tgcScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-be');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (tgcScoreCount shl 16), '-be');
end;
end;
+ end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
Result := (p.Team = TEAM_RED) or (p.Team = TEAM_BLUE);
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäå
Result := (p.Team = TEAM_RED) or (p.Team = TEAM_BLUE);
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäå
- if Data.ScoreTeam in [2..3] then
+ if tgcScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_RED, TRIGGER_SCORE_TEAM_FORCE_BLUE] then
begin
begin
- if (Data.ScoreAction = 0) and (Data.ScoreTeam = 2) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then
begin
begin
- Inc(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Scores
+ Inc(gTeamStat[TEAM_RED].Score, tgcScoreCount); // Red Scores
- if Data.ScoreCon then
+ if tgcScoreCon then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_RED], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_RED], tgcScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '+tr');
+ MH_SEND_GameEvent(NET_EV_SCORE, tgcScoreCount shl 16, '+tr');
end;
end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
- if (Data.ScoreAction = 1) and (Data.ScoreTeam = 2) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then
begin
begin
- Dec(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Fouls
+ Dec(gTeamStat[TEAM_RED].Score, tgcScoreCount); // Red Fouls
- if Data.ScoreCon then
+ if tgcScoreCon then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_RED], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_RED], tgcScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '-tr');
+ MH_SEND_GameEvent(NET_EV_SCORE, tgcScoreCount shl 16, '-tr');
end;
end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
- if (Data.ScoreAction = 0) and (Data.ScoreTeam = 3) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_ADD) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then
begin
begin
- Inc(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Scores
+ Inc(gTeamStat[TEAM_BLUE].Score, tgcScoreCount); // Blue Scores
- if Data.ScoreCon then
+ if tgcScoreCon then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_BLUE], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_BLUE], tgcScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '+tb');
+ MH_SEND_GameEvent(NET_EV_SCORE, tgcScoreCount shl 16, '+tb');
end;
end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
- if (Data.ScoreAction = 1) and (Data.ScoreTeam = 3) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_SUB) and (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then
begin
begin
- Dec(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Fouls
+ Dec(gTeamStat[TEAM_BLUE].Score, tgcScoreCount); // Blue Fouls
- if Data.ScoreCon then
+ if tgcScoreCon then
begin
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_BLUE], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_BLUE], tgcScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '-tb');
+ MH_SEND_GameEvent(NET_EV_SCORE, tgcScoreCount shl 16, '-tb');
end;
end;
- if Data.ScoreMsg then
+ if tgcScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
end;
end;
// Âûèãðûø
end;
end;
// Âûèãðûø
- if (Data.ScoreAction = 2) and (gGameSettings.GoalLimit > 0) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_WIN) and (gGameSettings.ScoreLimit > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (tgcScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_RED)) // Red Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
- if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
+ if ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) // Red Wins
+ or ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then
+ begin
+ if gTeamStat[TEAM_RED].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_RED].Score := gGameSettings.ScoreLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = 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
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
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wre');
end;
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wre');
end;
+ end;
Result := True;
end;
Result := True;
end;
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Blue Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
- if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
+ end;
+ if ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) // Blue Wins
+ or ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then
+ begin
+ if gTeamStat[TEAM_BLUE].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_BLUE].Score := gGameSettings.ScoreLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ begin
+ if (tgcScoreTeam = 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
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
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wbe');
end;
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE, p.UID, 'wbe');
end;
+ end;
Result := True;
end;
Result := True;
end;
+ end;
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
- if Data.ScoreTeam in [2..3] then
+ if tgcScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_RED, TRIGGER_SCORE_TEAM_FORCE_BLUE] then
begin
begin
- if Data.ScoreTeam = 2 then // Red Wins
- if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then // Red Wins
+ begin
+ if gTeamStat[TEAM_RED].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_RED].Score := gGameSettings.ScoreLimit;
Result := True;
end;
Result := True;
end;
- if Data.ScoreTeam = 3 then // Blue Wins
- if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
+ end;
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then // Blue Wins
+ begin
+ if gTeamStat[TEAM_BLUE].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_BLUE].Score := gGameSettings.ScoreLimit;
Result := True;
end;
Result := True;
end;
+ end;
end;
end;
// Ïðîèãðûø
end;
end;
// Ïðîèãðûø
- if (Data.ScoreAction = 3) and (gGameSettings.GoalLimit > 0) then
+ if (tgcScoreAction = TRIGGER_SCORE_ACTION_LOOSE) and (gGameSettings.ScoreLimit > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (tgcScoreTeam in [TRIGGER_SCORE_TEAM_MINE_RED, TRIGGER_SCORE_TEAM_MINE_BLUE]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Red Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
- if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
+ if ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_BLUE)) // Red Wins
+ or ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_RED)) then
+ if gTeamStat[TEAM_RED].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_RED].Score := gGameSettings.ScoreLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ if tgcScoreTeam = 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
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
Result := True;
end;
Result := True;
end;
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_RED)) // Blue Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
- if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
+ if ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_RED) and (p.Team = TEAM_RED)) // Blue Wins
+ or ((tgcScoreTeam = TRIGGER_SCORE_TEAM_MINE_BLUE) and (p.Team = TEAM_BLUE)) then
+ if gTeamStat[TEAM_BLUE].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_BLUE].Score := gGameSettings.ScoreLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if tgcScoreCon then
+ if tgcScoreTeam = 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
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
end;
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
end;
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
- if Data.ScoreTeam in [2..3] then
+ if tgcScoreTeam in [TRIGGER_SCORE_TEAM_FORCE_BLUE, TRIGGER_SCORE_TEAM_FORCE_RED] then
begin
begin
- if Data.ScoreTeam = 3 then // Red Wins
- if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_BLUE) then // Red Wins
+ begin
+ if gTeamStat[TEAM_RED].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_RED].Score := gGameSettings.ScoreLimit;
Result := True;
end;
Result := True;
end;
- if Data.ScoreTeam = 2 then // Blue Wins
- if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
+ end;
+ if (tgcScoreTeam = TRIGGER_SCORE_TEAM_FORCE_RED) then // Blue Wins
+ begin
+ if gTeamStat[TEAM_BLUE].Score < SmallInt(gGameSettings.ScoreLimit) then
begin
begin
- gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
+ gTeamStat[TEAM_BLUE].Score := gGameSettings.ScoreLimit;
Result := True;
end;
Result := True;
end;
+ end;
end;
end;
if Result then begin
end;
end;
if Result then begin
TRIGGER_MESSAGE:
begin
TRIGGER_MESSAGE:
begin
- Result := tr_Message(Data.MessageKind, Data.MessageText,
- Data.MessageSendTo, Data.MessageTime,
+ Result := tr_Message(tgcKind, tgcText,
+ tgcMsgDest, tgcMsgTime,
ActivateUID);
TimeOut := 18;
end;
ActivateUID);
TimeOut := 18;
end;
if coolDown then
begin
// Âñïîìèíàåì, àêòèâèðîâàë ëè îí ìåíÿ ðàíüøå
if coolDown then
begin
// Âñïîìèíàåì, àêòèâèðîâàë ëè îí ìåíÿ ðàíüøå
- for i := 0 to High(Activators) do
- if Activators[i].UID = ActivateUID then
+ for idx := 0 to High(Activators) do
+ if Activators[idx].UID = ActivateUID then
begin
begin
- k := i;
+ k := idx;
Break;
end;
if k = -1 then
Break;
end;
if k = -1 then
end else
begin // Óæå âèäåëè åãî
// Åñëè èíòåðâàë îòêëþ÷¸í, íî îí âñ¸ åù¸ â çîíå ïîðàæåíèÿ, äà¸ì åìó âðåìÿ
end else
begin // Óæå âèäåëè åãî
// Åñëè èíòåðâàë îòêëþ÷¸í, íî îí âñ¸ åù¸ â çîíå ïîðàæåíèÿ, äà¸ì åìó âðåìÿ
- if (Data.DamageInterval = 0) and (Activators[k].TimeOut > 0) then
+ if (tgcInterval = 0) and (Activators[k].TimeOut > 0) then
Activators[k].TimeOut := 65535;
// Òàéìàóò ïðîø¸ë - ðàáîòàåì
Result := Activators[k].TimeOut = 0;
Activators[k].TimeOut := 65535;
// Òàéìàóò ïðîø¸ë - ðàáîòàåì
Result := Activators[k].TimeOut = 0;
Exit;
// Íàíîñèì óðîí èãðîêó
Exit;
// Íàíîñèì óðîí èãðîêó
- if (TriggerType = TRIGGER_DAMAGE) and (Data.DamageValue > 0) then
- p.Damage(Data.DamageValue, 0, 0, 0, HIT_SOME);
+ if (TriggerType = TRIGGER_DAMAGE) and (tgcAmount > 0) then
+ begin
+ // Êèñëîòíûé óðîí íå íàíîñèòñÿ êîãäà åñòü êîñòþì
+ // "Âîäÿíîé" óðîí íå íàíîñèòñÿ êîãäà åñòü êèñëîðîä
+ if not (((tgcKind = HIT_ACID) and (p.FPowerups[MR_SUIT] > gTime)) or
+ ((tgcKind = HIT_WATER) and (p.Air > 0))) then
+ p.Damage(tgcAmount, 0, 0, 0, tgcKind);
+ if (tgcKind = HIT_FLAME) then p.CatchFire(0);
+ end;
// Ëå÷èì èãðîêà
// Ëå÷èì èãðîêà
- if (TriggerType = TRIGGER_HEALTH) and (Data.HealValue > 0) then
- if p.Heal(Data.HealValue, not Data.HealMax) and (not Data.HealSilent) then
+ if (TriggerType = TRIGGER_HEALTH) and (tgcAmount > 0) then
+ if p.Heal(tgcAmount, not tgcHealMax) and (not tgcSilent) then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', p.Obj.X, p.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', p.Obj.X, p.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
UID_MONSTER:
begin
UID_MONSTER:
begin
- m := g_Monsters_Get(ActivateUID);
+ m := g_Monsters_ByUID(ActivateUID);
if m = nil then
Exit;
// Íàíîñèì óðîí ìîíñòðó
if m = nil then
Exit;
// Íàíîñèì óðîí ìîíñòðó
- if (TriggerType = TRIGGER_DAMAGE) and (Data.DamageValue > 0) then
- m.Damage(Data.DamageValue, 0, 0, 0, HIT_SOME);
+ if (TriggerType = TRIGGER_DAMAGE) and (tgcAmount > 0) then
+ begin
+ m.Damage(tgcAmount, 0, 0, 0, tgcKind);
+ if (tgcKind = HIT_FLAME) then m.CatchFire(0);
+ end;
// Ëå÷èì ìîíñòðà
// Ëå÷èì ìîíñòðà
- if (TriggerType = TRIGGER_HEALTH) and (Data.HealValue > 0) then
- if m.Heal(Data.HealValue) and (not Data.HealSilent) then
+ if (TriggerType = TRIGGER_HEALTH) and (tgcAmount > 0) then
+ if m.Heal(tgcAmount) and (not tgcSilent) then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', m.Obj.X, m.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', m.Obj.X, m.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
end;
end;
// Íàçíà÷àåì âðåìÿ ñëåäóþùåãî âîçäåéñòâèÿ
end;
end;
// Íàçíà÷àåì âðåìÿ ñëåäóþùåãî âîçäåéñòâèÿ
- if TriggerType = TRIGGER_DAMAGE then
- i := Data.DamageInterval
- else
- i := Data.HealInterval;
+ idx := tgcInterval;
if coolDown then
if coolDown then
- if i > 0 then
- Activators[k].TimeOut := i
+ if idx > 0 then
+ Activators[k].TimeOut := idx
else
Activators[k].TimeOut := 65535;
end;
else
Activators[k].TimeOut := 65535;
end;
Exit;
// put this at the beginning so it doesn't trigger itself
Exit;
// put this at the beginning so it doesn't trigger itself
- TimeOut := Data.ShotWait + 1;
+ TimeOut := tgcWait + 1;
- wx := Data.ShotPos.X;
- wy := Data.ShotPos.Y;
- pAngle := -DegToRad(Data.ShotAngle);
+ wx := tgcTX;
+ wy := tgcTY;
+ pAngle := -DegToRad(tgcAngle);
xd := wx + Round(Cos(pAngle) * 32.0);
yd := wy + Round(Sin(pAngle) * 32.0);
TargetUID := 0;
xd := wx + Round(Cos(pAngle) * 32.0);
yd := wy + Round(Sin(pAngle) * 32.0);
TargetUID := 0;
- case Data.ShotTarget of
+ case tgcShotTarget of
TRIGGER_SHOT_TARGET_MON: // monsters
TRIGGER_SHOT_TARGET_MON: // monsters
- if gMonsters <> nil then
- for i := Low(gMonsters) to High(gMonsters) do
- if (gMonsters[i] <> nil) and gMonsters[i].Live and
- tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
- begin
- xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
- yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
- TargetUID := gMonsters[i].UID;
- break;
- end;
+ //TODO: accelerate this!
+ g_Mons_ForEachAlive(monsShotTarget);
TRIGGER_SHOT_TARGET_PLR: // players
if gPlayers <> nil then
TRIGGER_SHOT_TARGET_PLR: // players
if gPlayers <> nil then
- for i := Low(gPlayers) to High(gPlayers) do
- if (gPlayers[i] <> nil) and gPlayers[i].Live and
- tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
+ for idx := Low(gPlayers) to High(gPlayers) do
+ if (gPlayers[idx] <> nil) and gPlayers[idx].alive and
+ tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then
begin
begin
- xd := gPlayers[i].GameX + PLAYER_RECT_CX;
- yd := gPlayers[i].GameY + PLAYER_RECT_CY;
- TargetUID := gPlayers[i].UID;
+ xd := gPlayers[idx].GameX + PLAYER_RECT_CX;
+ yd := gPlayers[idx].GameY + PLAYER_RECT_CY;
+ TargetUID := gPlayers[idx].UID;
break;
end;
TRIGGER_SHOT_TARGET_RED: // red team
if gPlayers <> nil then
break;
end;
TRIGGER_SHOT_TARGET_RED: // red team
if gPlayers <> nil then
- for i := Low(gPlayers) to High(gPlayers) do
- if (gPlayers[i] <> nil) and gPlayers[i].Live and
- (gPlayers[i].Team = TEAM_RED) and
- tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
+ for idx := Low(gPlayers) to High(gPlayers) do
+ if (gPlayers[idx] <> nil) and gPlayers[idx].alive and
+ (gPlayers[idx].Team = TEAM_RED) and
+ tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then
begin
begin
- xd := gPlayers[i].GameX + PLAYER_RECT_CX;
- yd := gPlayers[i].GameY + PLAYER_RECT_CY;
- TargetUID := gPlayers[i].UID;
+ xd := gPlayers[idx].GameX + PLAYER_RECT_CX;
+ yd := gPlayers[idx].GameY + PLAYER_RECT_CY;
+ TargetUID := gPlayers[idx].UID;
break;
end;
TRIGGER_SHOT_TARGET_BLUE: // blue team
if gPlayers <> nil then
break;
end;
TRIGGER_SHOT_TARGET_BLUE: // blue team
if gPlayers <> nil then
- for i := Low(gPlayers) to High(gPlayers) do
- if (gPlayers[i] <> nil) and gPlayers[i].Live and
- (gPlayers[i].Team = TEAM_BLUE) and
- tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
+ for idx := Low(gPlayers) to High(gPlayers) do
+ if (gPlayers[idx] <> nil) and gPlayers[idx].alive and
+ (gPlayers[idx].Team = TEAM_BLUE) and
+ tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then
begin
begin
- xd := gPlayers[i].GameX + PLAYER_RECT_CX;
- yd := gPlayers[i].GameY + PLAYER_RECT_CY;
- TargetUID := gPlayers[i].UID;
+ xd := gPlayers[idx].GameX + PLAYER_RECT_CX;
+ yd := gPlayers[idx].GameY + PLAYER_RECT_CY;
+ TargetUID := gPlayers[idx].UID;
break;
end;
TRIGGER_SHOT_TARGET_MONPLR: // monsters then players
begin
break;
end;
TRIGGER_SHOT_TARGET_MONPLR: // monsters then players
begin
- if gMonsters <> nil then
- for i := Low(gMonsters) to High(gMonsters) do
- if (gMonsters[i] <> nil) and gMonsters[i].Live and
- tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
- begin
- xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
- yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
- TargetUID := gMonsters[i].UID;
- break;
- end;
+ //TODO: accelerate this!
+ g_Mons_ForEachAlive(monsShotTargetMonPlr);
+
if (TargetUID = 0) and (gPlayers <> nil) then
if (TargetUID = 0) and (gPlayers <> nil) then
- for i := Low(gPlayers) to High(gPlayers) do
- if (gPlayers[i] <> nil) and gPlayers[i].Live and
- tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
+ for idx := Low(gPlayers) to High(gPlayers) do
+ if (gPlayers[idx] <> nil) and gPlayers[idx].alive and
+ tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then
begin
begin
- xd := gPlayers[i].GameX + PLAYER_RECT_CX;
- yd := gPlayers[i].GameY + PLAYER_RECT_CY;
- TargetUID := gPlayers[i].UID;
+ xd := gPlayers[idx].GameX + PLAYER_RECT_CX;
+ yd := gPlayers[idx].GameY + PLAYER_RECT_CY;
+ TargetUID := gPlayers[idx].UID;
break;
end;
end;
break;
end;
end;
TRIGGER_SHOT_TARGET_PLRMON: // players then monsters
begin
if gPlayers <> nil then
TRIGGER_SHOT_TARGET_PLRMON: // players then monsters
begin
if gPlayers <> nil then
- for i := Low(gPlayers) to High(gPlayers) do
- if (gPlayers[i] <> nil) and gPlayers[i].Live and
- tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
+ for idx := Low(gPlayers) to High(gPlayers) do
+ if (gPlayers[idx] <> nil) and gPlayers[idx].alive and
+ tr_ShotAimCheck(Trigger, @(gPlayers[idx].Obj)) then
begin
begin
- xd := gPlayers[i].GameX + PLAYER_RECT_CX;
- yd := gPlayers[i].GameY + PLAYER_RECT_CY;
- TargetUID := gPlayers[i].UID;
- break;
- end;
- if (TargetUID = 0) and (gMonsters <> nil) then
- for i := Low(gMonsters) to High(gMonsters) do
- if (gMonsters[i] <> nil) and gMonsters[i].Live and
- tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
- begin
- xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
- yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
- TargetUID := gMonsters[i].UID;
+ xd := gPlayers[idx].GameX + PLAYER_RECT_CX;
+ yd := gPlayers[idx].GameY + PLAYER_RECT_CY;
+ TargetUID := gPlayers[idx].UID;
break;
end;
break;
end;
+ if TargetUID = 0 then
+ begin
+ //TODO: accelerate this!
+ g_Mons_ForEachAlive(monShotTargetPlrMon);
+ end;
end;
else begin
end;
else begin
- if (Data.ShotTarget <> TRIGGER_SHOT_TARGET_NONE) or
- (Data.ShotType <> TRIGGER_SHOT_REV) then
+ if (tgcShotTarget <> TRIGGER_SHOT_TARGET_NONE) or
+ (tgcShotType <> TRIGGER_SHOT_REV) then
TargetUID := ActivateUID;
end;
end;
TargetUID := ActivateUID;
end;
end;
- if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or
- ((Data.ShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then
+ if (tgcShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or
+ ((tgcShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then
begin
Result := True;
begin
Result := True;
- if (Data.ShotIntSight = 0) or
- (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or
+ if (tgcSight = 0) or
+ (tgcShotTarget = TRIGGER_SHOT_TARGET_NONE) or
(TargetUID = ShotSightTarget) then
MakeShot(Trigger, wx, wy, xd, yd, TargetUID)
else
begin
(TargetUID = ShotSightTarget) then
MakeShot(Trigger, wx, wy, xd, yd, TargetUID)
else
begin
- ShotSightTime := Data.ShotIntSight;
+ ShotSightTime := tgcSight;
ShotSightTargetN := TargetUID;
ShotSightTargetN := TargetUID;
- if Data.ShotType = TRIGGER_SHOT_BFG then
+ if tgcShotType = TRIGGER_SHOT_BFG then
begin
g_Sound_PlayExAt('SOUND_WEAPON_STARTFIREBFG', wx, wy);
if g_Game_IsNet and g_Game_IsServer then
begin
g_Sound_PlayExAt('SOUND_WEAPON_STARTFIREBFG', wx, wy);
if g_Game_IsNet and g_Game_IsServer then
TRIGGER_EFFECT:
begin
TRIGGER_EFFECT:
begin
- i := Data.FXCount;
+ idx := tgcFXCount;
- while i > 0 do
+ while idx > 0 do
begin
begin
- case Data.FXPos of
+ case tgcFXPos of
TRIGGER_EFFECT_POS_CENTER:
begin
wx := X + Width div 2;
TRIGGER_EFFECT_POS_CENTER:
begin
wx := X + Width div 2;
wy := Y + Height div 2;
end;
end;
wy := Y + Height div 2;
end;
end;
- xd := Data.FXVelX;
- yd := Data.FXVelY;
- if Data.FXSpreadL > 0 then xd := xd - Random(Data.FXSpreadL + 1);
- if Data.FXSpreadR > 0 then xd := xd + Random(Data.FXSpreadR + 1);
- if Data.FXSpreadU > 0 then yd := yd - Random(Data.FXSpreadU + 1);
- if Data.FXSpreadD > 0 then yd := yd + Random(Data.FXSpreadD + 1);
+ xd := tgcVelX;
+ yd := tgcVelY;
+ if tgcSpreadL > 0 then xd -= Random(tgcSpreadL+1);
+ if tgcSpreadR > 0 then xd += Random(tgcSpreadR+1);
+ if tgcSpreadU > 0 then yd -= Random(tgcSpreadU+1);
+ if tgcSpreadD > 0 then yd += Random(tgcSpreadD+1);
tr_MakeEffect(wx, wy, xd, yd,
tr_MakeEffect(wx, wy, xd, yd,
- Data.FXType, Data.FXSubType,
- Data.FXColorR, Data.FXColorG, Data.FXColorB, True, False);
- Dec(i);
+ tgcFXType, tgcFXSubType,
+ tgcFXRed, tgcFXGreen, tgcFXBlue, True, False);
+ Dec(idx);
end;
end;
- TimeOut := Data.FXWait;
+ TimeOut := tgcWait;
+ result := true;
end;
end;
end;
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 (aTrigger: 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');
+ aTrigger.mapIndex := mapidx;
+ result := g_Triggers_Create(aTrigger, triggers.itemAt[mapidx], arridx);
end;
end;
-function g_Triggers_Create(Trigger: TTrigger): DWORD;
+
+function g_Triggers_Create (aTrigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD;
var
find_id: DWORD;
var
find_id: DWORD;
- fn, mapw: String;
+ fn: AnsiString;
+ f, olen: Integer;
+ ptg: PTrigger;
begin
begin
-// Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà:
- if (Trigger.TriggerType = TRIGGER_EXIT) and
- (not LongBool(gGameSettings.Options and GAME_OPTION_ALLOWEXIT)) then
- Trigger.TriggerType := TRIGGER_NONE;
-
-// Åñëè ìîíñòðû çàïðåùåíû, îòìåíÿåì òðèããåð:
- if (Trigger.TriggerType = TRIGGER_SPAWNMONSTER) and
- (not LongBool(gGameSettings.Options and GAME_OPTION_MONSTERS)) and
+ if (tgscope = nil) then tgscope := TTrigScope.Create();
+ if (tgclist = nil) then tgclist := TMyConstList.Create();
+
+ // Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà
+ if (aTrigger.TriggerType = TRIGGER_EXIT) and
+ (not (TGameOption.ALLOW_EXIT in gGameSettings.Options)) then
+ begin
+ aTrigger.TriggerType := TRIGGER_NONE;
+ end;
+
+ // Åñëè ìîíñòðû çàïðåùåíû, îòìåíÿåì òðèããåð
+ if (aTrigger.TriggerType = TRIGGER_SPAWNMONSTER) and
+ (not (TGameOption.MONSTERS in gGameSettings.Options)) and
(gGameSettings.GameType <> GT_SINGLE) then
(gGameSettings.GameType <> GT_SINGLE) then
- Trigger.TriggerType := TRIGGER_NONE;
+ begin
+ aTrigger.TriggerType := TRIGGER_NONE;
+ end;
+
+ // Ñ÷èòàåì êîëè÷åñòâî ñåêðåòîâ íà êàðòå
+ if (aTrigger.TriggerType = TRIGGER_SECRET) then gSecretsCount += 1;
-// Ñ÷èòàåì êîëè÷åñòâî ñåêðåòîâ íà êàðòå:
- if Trigger.TriggerType = TRIGGER_SECRET then
- gSecretsCount := gSecretsCount + 1;
+ 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
+ begin
+ gTriggers[f].TriggerType := TRIGGER_NONE;
+ gTriggers[f].trigDataRec := nil;
+ gTriggers[f].exoInit := nil;
+ gTriggers[f].exoThink := nil;
+ gTriggers[f].exoCheck := nil;
+ gTriggers[f].exoAction := nil;
+ gTriggers[f].userVars := nil;
+ end;
+ end;
+ f := forceInternalIndex;
+ gTriggers[f].trigDataRec.Free();
+ gTriggers[f].exoInit.Free();
+ gTriggers[f].exoThink.Free();
+ gTriggers[f].exoCheck.Free();
+ gTriggers[f].exoAction.Free();
+ gTriggers[f].userVars.Free();
+ gTriggers[f].trigDataRec := nil;
+ gTriggers[f].exoInit := nil;
+ gTriggers[f].exoThink := nil;
+ gTriggers[f].exoCheck := nil;
+ gTriggers[f].exoAction := nil;
+ gTriggers[f].userVars := nil;
+ find_id := DWORD(forceInternalIndex);
+ end;
+ gTriggers[find_id] := aTrigger;
+ ptg := @gTriggers[find_id];
- find_id := FindTrigger();
- gTriggers[find_id] := Trigger;
+ ptg.mapId := trec.id;
+ // clone trigger data
+ if (trec.trigRec = nil) then
+ begin
+ ptg.trigDataRec := nil;
+ //HACK!
+ if (ptg.TriggerType <> TRIGGER_SECRET) then
+ begin
+ e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [ptg.TriggerType], TMsgType.Warning);
+ end;
+ end
+ else
+ begin
+ ptg.trigDataRec := trec.trigRec.clone(nil);
+ end;
- with gTriggers[find_id] do
+ with ptg^ do
begin
ID := find_id;
// if this type of trigger exists both on the client and on the server
// use an uniform numeration
begin
ID := find_id;
// if this type of trigger exists both on the client and on the server
// use an uniform numeration
- if Trigger.TriggerType = TRIGGER_SOUND then
+ ClientID := 0;
+ if (ptg.TriggerType = TRIGGER_SOUND) then
begin
Inc(gTriggerClientID);
ClientID := gTriggerClientID;
begin
Inc(gTriggerClientID);
ClientID := gTriggerClientID;
- end
- else
- ClientID := 0;
+ end;
TimeOut := 0;
ActivateUID := 0;
PlayerCollide := False;
TimeOut := 0;
ActivateUID := 0;
PlayerCollide := False;
SpawnedCount := 0;
end;
SpawnedCount := 0;
end;
-// Çàãðóæàåì çâóê, åñëè ýòî òðèããåð "Çâóê":
- if (Trigger.TriggerType = TRIGGER_SOUND) and
- (Trigger.Data.SoundName <> '') then
- begin
- // Åùå íåò òàêîãî çâóêà:
- if not g_Sound_Exists(Trigger.Data.SoundName) then
- begin
- fn := g_ExtractWadName(Trigger.Data.SoundName);
+ // update cached trigger variables
+ trigUpdateCacheData(ptg^, ptg.trigDataRec);
- if fn = '' then
- begin // Çâóê â ôàéëå ñ êàðòîé
- mapw := g_ExtractWadName(gMapInfo.Map);
- fn := mapw+':'+g_ExtractFilePathName(Trigger.Data.SoundName);
- end
- else // Çâóê â îòäåëüíîì ôàéëå
- fn := GameDir + '/wads/' + Trigger.Data.SoundName;
+ ptg.userVars := nil;
+
+ try
+ ptg.exoThink := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_think']));
+ except
+ on e: TExomaParseException do
+ begin
+ conwritefln('*** ERROR parsing exoma_think (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_think'])]);
+ ptg.exoThink := nil;
+ end;
+ else
+ raise;
+ end;
+ try
+ ptg.exoCheck := TExprBase.parse(tgclist, VarToStr(trec.user['exoma_check']));
+ except
+ on e: TExomaParseException do
+ begin
+ conwritefln('*** ERROR parsing exoma_check (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_check'])]);
+ ptg.exoCheck := nil;
+ end;
+ else
+ raise;
+ end;
+ try
+ ptg.exoAction := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_action']));
+ except
+ on e: TExomaParseException do
+ begin
+ conwritefln('*** ERROR parsing exoma_action (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_action'])]);
+ ptg.exoAction := nil;
+ end;
+ else
+ raise;
+ end;
+ try
+ ptg.exoInit := TExprBase.parseStatList(tgclist, VarToStr(trec.user['exoma_init']));
+ except
+ on e: TExomaParseException do
+ begin
+ conwritefln('*** ERROR parsing exoma_init (%s,%s): %s [%s]', [e.tokLine, e.tokCol, e.message, VarToStr(trec.user['exoma_init'])]);
+ ptg.exoInit := nil;
+ end;
+ else
+ raise;
+ end;
+
+ if (forceInternalIndex < 0) and (ptg.exoInit <> nil) then
+ begin
+ //conwritefln('executing trigger init: [%s]', [gTriggers[find_id].exoInit.toString()]);
+ try
+ tgscope.me := ptg;
+ ptg.exoInit.value(tgscope);
+ tgscope.me := nil;
+ except
+ tgscope.me := nil;
+ conwritefln('*** trigger exoactivate error: %s', [ptg.exoInit.toString()]);
+ exit;
+ end;
+ end;
- if not g_Sound_CreateWADEx(Trigger.Data.SoundName, fn) then
- g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.Data.SoundName]));
+ // Çàãðóæàåì çâóê, åñëè ýòî òðèããåð "Çâóê"
+ if (ptg.TriggerType = TRIGGER_SOUND) and (ptg.tgcSoundName <> '') then
+ begin
+ // Åùå íåò òàêîãî çâóêà
+ if not g_Sound_Exists(ptg.tgcSoundName) then
+ begin
+ fn := e_GetResourcePath(WadDirs, ptg.tgcSoundName, g_ExtractWadName(gMapInfo.Map));
+ //e_LogWritefln('loading trigger sound ''%s''', [fn]);
+ if not g_Sound_CreateWADEx(ptg.tgcSoundName, fn) then
+ begin
+ g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, ptg.tgcSoundName]));
+ end;
end;
end;
- // Ñîçäàåì îáúåêò çâóêà:
- with gTriggers[find_id] do
+ // Ñîçäàåì îáúåêò çâóêà
+ with ptg^ do
begin
Sound := TPlayableSound.Create();
begin
Sound := TPlayableSound.Create();
- if not Sound.SetByName(Trigger.Data.SoundName) then
+ if not Sound.SetByName(ptg.tgcSoundName) then
begin
Sound.Free();
Sound := nil;
begin
Sound.Free();
Sound := nil;
end;
end;
end;
end;
-// Çàãðóæàåì ìóçûêó, åñëè ýòî òðèããåð "Ìóçûêà":
- if (Trigger.TriggerType = TRIGGER_MUSIC) and
- (Trigger.Data.MusicName <> '') then
+ // Çàãðóæàåì ìóçûêó, åñëè ýòî òðèããåð "Ìóçûêà"
+ if (ptg.TriggerType = TRIGGER_MUSIC) and (ptg.tgcMusicName <> '') then
begin
begin
- // Åùå íåò òàêîé ìóçûêè:
- if not g_Sound_Exists(Trigger.Data.MusicName) then
+ // Åùå íåò òàêîé ìóçûêè
+ if not g_Sound_Exists(ptg.tgcMusicName) then
begin
begin
- fn := g_ExtractWadName(Trigger.Data.MusicName);
-
- if fn = '' then
- begin // Ìóçûêà â ôàéëå ñ êàðòîé
- mapw := g_ExtractWadName(gMapInfo.Map);
- fn := mapw+':'+g_ExtractFilePathName(Trigger.Data.MusicName);
- end
- else // Ìóçûêà â ôàéëå ñ êàðòîé
- fn := GameDir+'/wads/'+Trigger.Data.MusicName;
-
- if not g_Sound_CreateWADEx(Trigger.Data.MusicName, fn, True) then
- g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.Data.MusicName]));
+ fn := e_GetResourcePath(WadDirs, ptg.tgcMusicName, g_ExtractWadName(gMapInfo.Map));
+ if not g_Sound_CreateWADEx(ptg.tgcMusicName, fn, True) then
+ begin
+ g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, ptg.tgcMusicName]));
+ end;
end;
end;
end;
end;
-// Çàãðóæàåì äàííûå òðèããåðà "Òóðåëü":
- if Trigger.TriggerType = TRIGGER_SHOT then
- with gTriggers[find_id] do
+ // Çàãðóæàåì äàííûå òðèããåðà "Òóðåëü"
+ if (ptg.TriggerType = TRIGGER_SHOT) then
+ begin
+ with ptg^ do
begin
ShotPanelTime := 0;
ShotSightTime := 0;
ShotSightTimeout := 0;
ShotSightTarget := 0;
ShotSightTargetN := 0;
begin
ShotPanelTime := 0;
ShotSightTime := 0;
ShotSightTimeout := 0;
ShotSightTarget := 0;
ShotSightTargetN := 0;
- ShotAmmoCount := Trigger.Data.ShotAmmo;
+ ShotAmmoCount := ptg.tgcAmmo;
ShotReloadTime := 0;
end;
ShotReloadTime := 0;
end;
+ end;
Result := find_id;
end;
Result := find_id;
end;
+
+// sorry; grid doesn't support recursive queries, so we have to do this
+type
+ TSimpleMonsterList = specialize TSimpleList<TMonster>;
+
+var
+ tgMonsList: TSimpleMonsterList = nil;
+
procedure g_Triggers_Update();
var
a, b, i: Integer;
Affected: array of Integer;
procedure g_Triggers_Update();
var
a, b, i: Integer;
Affected: array of Integer;
+
+ function monsNear (mon: TMonster): Boolean;
+ begin
+ result := false; // don't stop
+ {
+ gTriggers[a].ActivateUID := mon.UID;
+ ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+ }
+ tgMonsList.append(mon);
+ end;
+
+var
+ mon: TMonster;
+ pan: TPanel;
begin
begin
- if gTriggers = nil then
- Exit;
+ if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create();
+
+ if gTriggers = nil then Exit;
+ if gLMSRespawn > LMS_RESPAWN_NONE then Exit; // don't update triggers at all
+
SetLength(Affected, 0);
for a := 0 to High(gTriggers) do
SetLength(Affected, 0);
for a := 0 to High(gTriggers) do
// Åñòü òðèããåð:
if TriggerType <> TRIGGER_NONE then
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
if (TriggerType = TRIGGER_DAMAGE) or (TriggerType = TRIGGER_HEALTH) then
+ begin
for b := 0 to High(Activators) do
begin
// Óìåíüøàåì âðåìÿ äî ïîâòîðíîãî âîçäåéñòâèÿ:
if Activators[b].TimeOut > 0 then
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
else
- Continue;
+ begin
+ continue;
+ end;
// Ñ÷èòàåì, ÷òî îáúåêò ïîêèíóë çîíó äåéñòâèÿ òðèããåðà
// Ñ÷èòàåì, ÷òî îáúåêò ïîêèíóë çîíó äåéñòâèÿ òðèããåðà
- if (Data.DamageInterval = 0) and (Activators[b].TimeOut < 65530) then
- Activators[b].TimeOut := 0;
+ if (tgcInterval = 0) and (Activators[b].TimeOut < 65530) then Activators[b].TimeOut := 0;
end;
end;
+ end;
- // Îáðàáàòûâàåì ñïàâíåðû:
+ // Îáðàáàòûâàåì ñïàâíåðû
if Enabled and AutoSpawn then
if Enabled and AutoSpawn then
+ begin
if SpawnCooldown = 0 then
begin
if SpawnCooldown = 0 then
begin
- // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà:
- if (TriggerType = TRIGGER_SPAWNMONSTER) and (Data.MonDelay > 0) then
+ // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà
+ if (TriggerType = TRIGGER_SPAWNMONSTER) and (tgcDelay > 0) then
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
end;
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
end;
- // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò:
- if (TriggerType = TRIGGER_SPAWNITEM) and (Data.ItemDelay > 0) then
+ // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò
+ if (TriggerType = TRIGGER_SPAWNITEM) and (tgcDelay > 0) then
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
end;
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
end;
- end else // Óìåíüøàåì âðåìÿ îæèäàíèÿ:
+ end
+ else
+ begin
+ // Óìåíüøàåì âðåìÿ îæèäàíèÿ
Dec(SpawnCooldown);
Dec(SpawnCooldown);
+ end;
+ end;
- // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü":
+ // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü"
if TriggerType = TRIGGER_SHOT then
begin
if ShotPanelTime > 0 then
begin
Dec(ShotPanelTime);
if TriggerType = TRIGGER_SHOT then
begin
if ShotPanelTime > 0 then
begin
Dec(ShotPanelTime);
- if ShotPanelTime = 0 then
- g_Map_SwitchTexture(ShotPanelType, Data.ShotPanelID);
+ if ShotPanelTime = 0 then g_Map_SwitchTextureGUID({ShotPanelType,} trigPanelGUID);
end;
if ShotSightTime > 0 then
begin
Dec(ShotSightTime);
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);
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);
end;
if ShotReloadTime > 0 then
begin
Dec(ShotReloadTime);
- if ShotReloadTime = 0 then
- ShotAmmoCount := Data.ShotAmmo;
+ if ShotReloadTime = 0 then ShotAmmoCount := tgcAmmo;
end;
end;
end;
end;
- // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì:
+ // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì
if Enabled and (TriggerType = TRIGGER_SOUND) and (Sound <> nil) then
if Enabled and (TriggerType = TRIGGER_SOUND) and (Sound <> nil) then
+ begin
if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then
begin
if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then
begin
- if Data.PlayCount > 0 then // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî
- SoundPlayCount := SoundPlayCount - 1;
- if Data.Local then
- Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), Data.Volume/255.0)
+ if tgcPlayCount > 0 then Dec(SoundPlayCount); (* looped sound if zero *)
+ if tgcLocal then
+ Sound.PlayVolumeAtRect(X, Y, Width, Height, tgcVolume / 255.0)
else
else
- Sound.PlayPanVolume((Data.Pan-127.0)/128.0, Data.Volume/255.0);
+ Sound.PlayPanVolume((tgcPan - 127.0) / 128.0, tgcVolume / 255.0);
if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then
if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then
- MH_SEND_TriggerSound(gTriggers[a]);
- end;
+ MH_SEND_TriggerSound(gTriggers[a])
+ end
+ end;
- // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü:
- if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (Data.PanelID <> -1) then
+ // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü
+ if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then
begin
begin
- tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ tr_OpenDoor(trigPanelGUID, tgcSilent, tgcD2d);
DoorTime := -1;
end;
DoorTime := -1;
end;
- // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü:
- if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (Data.PanelID <> -1) then
+ // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü
+ if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then
begin
begin
- // Óæå çàêðûòà:
- if gWalls[Data.PanelID].Enabled then
- DoorTime := -1
- else // Ïîêà îòêðûòà - çàêðûâàåì
- if tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_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;
DoorTime := -1;
+ end
+ else
+ begin
+ // Ïîêà îòêðûòà - çàêðûâàåì
+ if tr_CloseDoor(trigPanelGUID, tgcSilent, tgcD2d) then DoorTime := -1;
+ end;
+ end;
end;
// Òðèããåð - ðàñøèðèòåëü èëè ïåðåêëþ÷àòåëü, è ïðîøëà çàäåðæêà, è íàæàëè íóæíîå ÷èñëî ðàç:
if (TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF]) and
end;
// Òðèããåð - ðàñøèðèòåëü èëè ïåðåêëþ÷àòåëü, è ïðîøëà çàäåðæêà, è íàæàëè íóæíîå ÷èñëî ðàç:
if (TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF]) and
- (PressTime = 0) and (PressCount >= Data.Count) then
+ (PressTime = 0) and (PressCount >= tgcPressCount) then
begin
begin
- // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè:
+ // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè:
PressTime := -1;
PressTime := -1;
- // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé:
- if Data.Count > 0 then
- PressCount := PressCount - Data.Count
- else
- PressCount := 0;
+ // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé:
+ if tgcPressCount > 0 then PressCount -= tgcPressCount else PressCount := 0;
- // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû:
+ // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû:
for b := 0 to High(gTriggers) do
for b := 0 to High(gTriggers) do
- if g_Collide(Data.tX, Data.tY, Data.tWidth, Data.tHeight, gTriggers[b].X, gTriggers[b].Y,
+ begin
+ if g_Collide(tgcTX, tgcTY, tgcTWidth, tgcTHeight, gTriggers[b].X, gTriggers[b].Y,
gTriggers[b].Width, gTriggers[b].Height) and
gTriggers[b].Width, gTriggers[b].Height) and
- ((b <> a) or (Data.Wait > 0)) then
+ ((b <> a) or (tgcWait > 0)) then
begin // Can be self-activated, if there is Data.Wait
begin // Can be self-activated, if there is Data.Wait
- if (not Data.ExtRandom) or gTriggers[b].Enabled then
+ if (not tgcExtRandom) or gTriggers[b].Enabled then
begin
SetLength(Affected, Length(Affected) + 1);
Affected[High(Affected)] := b;
end;
end;
begin
SetLength(Affected, Length(Affected) + 1);
Affected[High(Affected)] := b;
end;
end;
- // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì:
- if (TriggerType = TRIGGER_PRESS) and Data.ExtRandom then
+ 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;
+ if not tgcSilent and (Length(tgcSound) > 0) then
+ begin
+ g_Sound_PlayExAt(tgcSound, X, Y);
+ if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, tgcSound);
+ end;
+ end;
+
+ // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì:
+ if (TriggerType = TRIGGER_PRESS) and tgcExtRandom then
begin
if (Length(Affected) > 0) then
begin
begin
if (Length(Affected) > 0) then
begin
end;
end
else //  ïðîòèâíîì ñëó÷àå ðàáîòàåì êàê îáû÷íî:
end;
end
else //  ïðîòèâíîì ñëó÷àå ðàáîòàåì êàê îáû÷íî:
+ begin
for i := 0 to High(Affected) do
begin
b := Affected[i];
for i := 0 to High(Affected) do
begin
b := Affected[i];
end;
end;
end;
end;
end;
end;
+ end;
SetLength(Affected, 0);
end;
SetLength(Affected, 0);
end;
if gPlayers[b] <> nil then
with gPlayers[b] do
// Æèâ, åñòü íóæíûå êëþ÷è è îí ðÿäîì:
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;
Collide(X, Y, Width, Height) then
begin
gTriggers[a].ActivateUID := UID;
ActivateTrigger(gTriggers[a], 0);
end else
begin
ActivateTrigger(gTriggers[a], 0);
end else
begin
- // "Ìîíñòð áëèçêî":
+ // "Ìîíñòð áëèçêî"
if ByteBool(ActivateType and ACTIVATE_MONSTERCOLLIDE) and
(TimeOut = 0) and (Keys = 0) then // Åñëè íå íóæíû êëþ÷è
if ByteBool(ActivateType and ACTIVATE_MONSTERCOLLIDE) and
(TimeOut = 0) and (Keys = 0) then // Åñëè íå íóæíû êëþ÷è
- if gMonsters <> nil then
- for b := 0 to High(gMonsters) do
- if (gMonsters[b] <> nil) then
- with gMonsters[b] do
- if Collide(X, Y, Width, Height) then
- begin
- gTriggers[a].ActivateUID := UID;
- ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
- end;
+ begin
+ //g_Mons_ForEach(monsNear);
+ //Alive?!
+ tgMonsList.reset();
+ g_Mons_ForEachAt(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height, monsNear);
+ for mon in tgMonsList do
+ begin
+ gTriggers[a].ActivateUID := mon.UID;
+ ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+ end;
+ tgMonsList.reset(); // just in case
+ end;
- // "Ìîíñòðîâ íåò":
+ // "Ìîíñòðîâ íåò"
if ByteBool(ActivateType and ACTIVATE_NOMONSTER) and
(TimeOut = 0) and (Keys = 0) then
if ByteBool(ActivateType and ACTIVATE_NOMONSTER) and
(TimeOut = 0) and (Keys = 0) then
- if not g_CollideMonster(X, Y, Width, Height) then
+ if not g_Mons_IsAnyAliveAt(X, Y, Width, Height) then
begin
gTriggers[a].ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_NOMONSTER);
begin
gTriggers[a].ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_NOMONSTER);
procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0);
begin
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;
gTriggers[ID].ActivateUID := ActivateUID;
ActivateTrigger(gTriggers[ID], ActivateType);
end;
b := False;
for a := 0 to High(gTriggers) do
b := False;
for a := 0 to High(gTriggers) do
+ begin
with gTriggers[a] do
with gTriggers[a] do
+ begin
if (TriggerType = TRIGGER_OPENDOOR) or
(TriggerType = TRIGGER_DOOR5) or
(TriggerType = TRIGGER_DOOR) then
begin
if (TriggerType = TRIGGER_OPENDOOR) or
(TriggerType = TRIGGER_DOOR5) or
(TriggerType = TRIGGER_DOOR) then
begin
- tr_OpenDoor(Data.PanelID, True, Data.d2d_doors);
+ tr_OpenDoor(trigPanelGUID, True, tgcD2d);
if TriggerType = TRIGGER_DOOR5 then DoorTime := 180;
b := True;
end;
if TriggerType = TRIGGER_DOOR5 then DoorTime := 180;
b := True;
end;
+ end;
+ end;
if b then g_Sound_PlayEx('SOUND_GAME_DOOROPEN');
end;
if b then g_Sound_PlayEx('SOUND_GAME_DOOROPEN');
end;
procedure g_Triggers_DecreaseSpawner(ID: DWORD);
begin
if (gTriggers <> nil) then
procedure g_Triggers_DecreaseSpawner(ID: DWORD);
begin
if (gTriggers <> nil) then
- if gTriggers[ID].SpawnedCount > 0 then
- Dec(gTriggers[ID].SpawnedCount);
+ begin
+ if gTriggers[ID].tgcMax > 0 then
+ begin
+ if gTriggers[ID].SpawnedCount > 0 then
+ Dec(gTriggers[ID].SpawnedCount);
+ end;
+ if gTriggers[ID].tgcDelay > 0 then
+ begin
+ if gTriggers[ID].SpawnCooldown < 0 then
+ gTriggers[ID].SpawnCooldown := gTriggers[ID].tgcDelay;
+ end;
+ end;
end;
end;
-procedure g_Triggers_Free();
+procedure g_Triggers_Free ();
var
a: Integer;
begin
var
a: Integer;
begin
- if gTriggers <> nil then
- for a := 0 to High(gTriggers) do
+ for a := 0 to High(gTriggers) do
+ begin
+ if (gTriggers[a].TriggerType = TRIGGER_SOUND) then
begin
begin
- if gTriggers[a].TriggerType = TRIGGER_SOUND then
+ if g_Sound_Exists(gTriggers[a].tgcSoundName) then
begin
begin
- if g_Sound_Exists(gTriggers[a].Data.SoundName) then
- g_Sound_Delete(gTriggers[a].Data.SoundName);
-
- gTriggers[a].Sound.Free();
+ g_Sound_Delete(gTriggers[a].tgcSoundName);
end;
end;
- if gTriggers[a].Activators <> nil then
- SetLength(gTriggers[a].Activators, 0);
+ gTriggers[a].Sound.Free();
end;
end;
+ if (gTriggers[a].Activators <> nil) then
+ begin
+ SetLength(gTriggers[a].Activators, 0);
+ end;
+ gTriggers[a].trigDataRec.Free();
+
+ gTriggers[a].exoThink.Free();
+ gTriggers[a].exoCheck.Free();
+ gTriggers[a].exoAction.Free();
+ gTriggers[a].userVars.Free();
+ end;
gTriggers := nil;
gSecretsCount := 0;
SetLength(gMonstersSpawned, 0);
end;
gTriggers := nil;
gSecretsCount := 0;
SetLength(gMonstersSpawned, 0);
end;
-procedure g_Triggers_SaveState(var Mem: TBinMemoryWriter);
+
+procedure g_Triggers_SaveState (st: TStream);
var
var
- count, act_count, i, j: Integer;
- dw: DWORD;
+ count, actCount, i, j: Integer;
sg: Single;
b: Boolean;
sg: Single;
b: Boolean;
- p: Pointer;
+ kv: THashStrVariant.PEntry;
+ t: LongInt;
begin
begin
-// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ:
- count := 0;
- if gTriggers <> nil then
- for i := 0 to High(gTriggers) do
- count := count + 1;
-
- Mem := TBinMemoryWriter.Create((count+1) * 200);
-
-// Êîëè÷åñòâî òðèããåðîâ:
- Mem.WriteInt(count);
+ // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ
+ count := Length(gTriggers);
- if count = 0 then
- Exit;
+ // Êîëè÷åñòâî òðèããåðîâ
+ utils.writeInt(st, LongInt(count));
+ if (count = 0) then exit;
for i := 0 to High(gTriggers) do
begin
for i := 0 to High(gTriggers) do
begin
- // Ñèãíàòóðà òðèããåðà:
- dw := TRIGGER_SIGNATURE; // 'TRGR'
- Mem.WriteDWORD(dw);
- // Òèï òðèããåðà:
- Mem.WriteByte(gTriggers[i].TriggerType);
- // Ñïåöèàëüíûå äàííûå òðèããåðà:
- p := @gTriggers[i].Data;
- Mem.WriteMemory(p, SizeOf(TTriggerData));
- // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
- Mem.WriteInt(gTriggers[i].X);
- Mem.WriteInt(gTriggers[i].Y);
- // Ðàçìåðû:
- Mem.WriteWord(gTriggers[i].Width);
- Mem.WriteWord(gTriggers[i].Height);
- // Âêëþ÷åí ëè òðèããåð:
- Mem.WriteBoolean(gTriggers[i].Enabled);
- // Òèï àêòèâàöèè òðèããåðà:
- Mem.WriteByte(gTriggers[i].ActivateType);
- // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè:
- Mem.WriteByte(gTriggers[i].Keys);
- // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ:
- Mem.WriteInt(gTriggers[i].TexturePanel);
- // Òèï ýòîé ïàíåëè:
- Mem.WriteWord(gTriggers[i].TexturePanelType);
- // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
- Mem.WriteWord(gTriggers[i].TimeOut);
- // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
- Mem.WriteWord(gTriggers[i].ActivateUID);
- // Ñïèñîê UID-îâ îáúåêòîâ, êîòîðûå íàõîäèëèñü ïîä âîçäåéñòâèåì:
- act_count := Length(gTriggers[i].Activators);
- Mem.WriteInt(act_count);
- for j := 0 to act_count-1 do
+ // Ñèãíàòóðà òðèããåðà
+ utils.writeSign(st, 'TRGX');
+ utils.writeInt(st, Byte(0));
+ // Òèï òðèããåðà
+ utils.writeInt(st, Byte(gTriggers[i].TriggerType));
+ if (gTriggers[i].TriggerType = TRIGGER_NONE) then continue; // empty one
+ // Ñïåöèàëüíûå äàííûå òðèããåðà: ïîòîì èç êàðòû îïÿòü âûòàùèì; ñîõðàíèì òîëüêî èíäåêñ
+ utils.writeInt(st, LongInt(gTriggers[i].mapIndex));
+ // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà
+ utils.writeInt(st, LongInt(gTriggers[i].X));
+ utils.writeInt(st, LongInt(gTriggers[i].Y));
+ // Ðàçìåðû
+ utils.writeInt(st, Word(gTriggers[i].Width));
+ utils.writeInt(st, Word(gTriggers[i].Height));
+ // Âêëþ÷åí ëè òðèããåð
+ utils.writeBool(st, gTriggers[i].Enabled);
+ // Òèï àêòèâàöèè òðèããåðà
+ utils.writeInt(st, Byte(gTriggers[i].ActivateType));
+ // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè
+ utils.writeInt(st, Byte(gTriggers[i].Keys));
+ // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ
+ utils.writeInt(st, LongInt(gTriggers[i].TexturePanelGUID));
+ // Òèï ýòîé ïàíåëè
+ //Mem.WriteWord(gTriggers[i].TexturePanelType);
+ // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+ utils.writeInt(st, LongInt(gTriggers[i].trigPanelGUID));
+ // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè
+ utils.writeInt(st, Word(gTriggers[i].TimeOut));
+ // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð
+ utils.writeInt(st, Word(gTriggers[i].ActivateUID));
+ // Ñïèñîê UID-îâ îáúåêòîâ, êîòîðûå íàõîäèëèñü ïîä âîçäåéñòâèåì
+ actCount := Length(gTriggers[i].Activators);
+ utils.writeInt(st, LongInt(actCount));
+ for j := 0 to actCount-1 do
begin
// UID îáúåêòà
begin
// UID îáúåêòà
- Mem.WriteWord(gTriggers[i].Activators[j].UID);
+ utils.writeInt(st, Word(gTriggers[i].Activators[j].UID));
// Âðåìÿ îæèäàíèÿ
// Âðåìÿ îæèäàíèÿ
- Mem.WriteWord(gTriggers[i].Activators[j].TimeOut);
+ utils.writeInt(st, Word(gTriggers[i].Activators[j].TimeOut));
end;
end;
- // Ñòîèò ëè èãðîê â îáëàñòè òðèããåðà:
- Mem.WriteBoolean(gTriggers[i].PlayerCollide);
- // Âðåìÿ äî çàêðûòèÿ äâåðè:
- Mem.WriteInt(gTriggers[i].DoorTime);
- // Çàäåðæêà àêòèâàöèè:
- Mem.WriteInt(gTriggers[i].PressTime);
- // Ñ÷åò÷èê íàæàòèé:
- Mem.WriteInt(gTriggers[i].PressCount);
- // Ñïàâíåð àêòèâåí:
- Mem.WriteBoolean(gTriggers[i].AutoSpawn);
- // Çàäåðæêà ñïàâíåðà:
- Mem.WriteInt(gTriggers[i].SpawnCooldown);
- // Ñ÷åò÷èê ñîçäàíèÿ îáúåêòîâ:
- Mem.WriteInt(gTriggers[i].SpawnedCount);
- // Ñêîëüêî ðàç ïðîèãðàí çâóê:
- Mem.WriteInt(gTriggers[i].SoundPlayCount);
- // Ïðîèãðûâàåòñÿ ëè çâóê?
- if gTriggers[i].Sound <> nil then
- b := gTriggers[i].Sound.IsPlaying()
- else
- b := False;
- Mem.WriteBoolean(b);
+ // Ñòîèò ëè èãðîê â îáëàñòè òðèããåðà
+ utils.writeBool(st, gTriggers[i].PlayerCollide);
+ // Âðåìÿ äî çàêðûòèÿ äâåðè
+ utils.writeInt(st, LongInt(gTriggers[i].DoorTime));
+ // Çàäåðæêà àêòèâàöèè
+ utils.writeInt(st, LongInt(gTriggers[i].PressTime));
+ // Ñ÷åò÷èê íàæàòèé
+ utils.writeInt(st, LongInt(gTriggers[i].PressCount));
+ // Ñïàâíåð àêòèâåí
+ utils.writeBool(st, gTriggers[i].AutoSpawn);
+ // Çàäåðæêà ñïàâíåðà
+ utils.writeInt(st, LongInt(gTriggers[i].SpawnCooldown));
+ // Ñ÷åò÷èê ñîçäàíèÿ îáúåêòîâ
+ utils.writeInt(st, LongInt(gTriggers[i].SpawnedCount));
+ // Ñêîëüêî ðàç ïðîèãðàí çâóê
+ utils.writeInt(st, LongInt(gTriggers[i].SoundPlayCount));
+ // Ïðîèãðûâàåòñÿ ëè çâóê?
+ if (gTriggers[i].Sound <> nil) then b := gTriggers[i].Sound.IsPlaying() else b := false;
+ utils.writeBool(st, b);
if b then
begin
if b then
begin
- // Ïîçèöèÿ ïðîèãðûâàíèÿ çâóêà:
- dw := gTriggers[i].Sound.GetPosition();
- Mem.WriteDWORD(dw);
- // Ãðîìêîñòü çâóêà:
+ // Ïîçèöèÿ ïðîèãðûâàíèÿ çâóêà
+ utils.writeInt(st, LongWord(gTriggers[i].Sound.GetPosition()));
+ // Ãðîìêîñòü çâóêà
sg := gTriggers[i].Sound.GetVolume();
sg := gTriggers[i].Sound.GetVolume();
- sg := sg / (gSoundLevel/255.0);
- Mem.WriteSingle(sg);
- // Ñòåðåî ñìåùåíèå çâóêà:
+ sg := sg/(gSoundLevel/255.0);
+ //Mem.WriteSingle(sg);
+ st.WriteBuffer(sg, sizeof(sg)); // sorry
+ // Ñòåðåî ñìåùåíèå çâóêà
sg := gTriggers[i].Sound.GetPan();
sg := gTriggers[i].Sound.GetPan();
- Mem.WriteSingle(sg);
+ //Mem.WriteSingle(sg);
+ st.WriteBuffer(sg, sizeof(sg)); // sorry
+ end;
+ // uservars
+ if (gTriggers[i].userVars = nil) then
+ begin
+ utils.writeInt(st, LongInt(0));
+ end
+ else
+ begin
+ utils.writeInt(st, LongInt(gTriggers[i].userVars.count)); //FIXME: check for overflow
+ for kv in gTriggers[i].userVars.byKeyValue do
+ begin
+ //writeln('<', kv.key, '>:<', VarToStr(kv.value), '>');
+ utils.writeStr(st, kv.key);
+ t := LongInt(varType(kv.value));
+ utils.writeInt(st, LongInt(t));
+ case t of
+ varString: utils.writeStr(st, AnsiString(kv.value));
+ varBoolean: utils.writeBool(st, Boolean(kv.value));
+ varShortInt: utils.writeInt(st, LongInt(kv.value));
+ varSmallint: utils.writeInt(st, LongInt(kv.value));
+ varInteger: utils.writeInt(st, LongInt(kv.value));
+ //varInt64: Mem.WriteInt(Integer(kv.value));
+ varByte: utils.writeInt(st, LongInt(kv.value));
+ varWord: utils.writeInt(st, LongInt(kv.value));
+ varLongWord: utils.writeInt(st, LongInt(kv.value));
+ //varQWord:
+ else raise Exception.CreateFmt('cannot save uservar ''%s''', [kv.key]);
+ end;
+ end;
end;
end;
end;
end;
end;
end;
-procedure g_Triggers_LoadState(var Mem: TBinMemoryReader);
+
+procedure g_Triggers_LoadState (st: TStream);
var
var
- count, act_count, i, j, a: Integer;
+ count, actCount, i, j, a: Integer;
dw: DWORD;
vol, pan: Single;
b: Boolean;
dw: DWORD;
vol, pan: Single;
b: Boolean;
- p: Pointer;
Trig: TTrigger;
Trig: TTrigger;
+ mapIndex: Integer;
+ uvcount: Integer;
+ vt: LongInt;
+ vv: Variant;
+ uvname: AnsiString = '';
+ ustr: AnsiString = '';
+ uint: LongInt;
+ ubool: Boolean;
begin
begin
- if Mem = nil then
- Exit;
+ assert(st <> nil);
g_Triggers_Free();
g_Triggers_Free();
-// Êîëè÷åñòâî òðèããåðîâ:
- Mem.ReadInt(count);
-
- if count = 0 then
- Exit;
+ // Êîëè÷åñòâî òðèããåðîâ
+ count := utils.readLongInt(st);
+ if (count = 0) then exit;
+ if (count < 0) or (count > 1024*1024) then raise XStreamError.Create('invalid trigger count');
for a := 0 to count-1 do
begin
for a := 0 to count-1 do
begin
- // Ñèãíàòóðà òðèããåðà:
- Mem.ReadDWORD(dw);
- if dw <> TRIGGER_SIGNATURE then // 'TRGR'
- begin
- raise EBinSizeError.Create('g_Triggers_LoadState: Wrong Trigger Signature');
- end;
- // Òèï òðèããåðà:
- Mem.ReadByte(Trig.TriggerType);
- // Ñïåöèàëüíûå äàííûå òðèããåðà:
- Mem.ReadMemory(p, dw);
- if dw <> SizeOf(TTriggerData) then
+ // Ñèãíàòóðà òðèããåðà
+ if not utils.checkSign(st, 'TRGX') then raise XStreamError.Create('invalid trigger signature');
+ if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid trigger version');
+ // Òèï òðèããåðà
+ Trig.TriggerType := utils.readByte(st);
+ if (Trig.TriggerType = TRIGGER_NONE) then continue; // empty one
+ // Ñïåöèàëüíûå äàííûå òðèããåðà: èíäåêñ â gCurrentMap.field['triggers']
+ mapIndex := utils.readLongInt(st);
+ i := g_Triggers_CreateWithMapIndex(Trig, a, mapIndex);
+ // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà
+ gTriggers[i].X := utils.readLongInt(st);
+ gTriggers[i].Y := utils.readLongInt(st);
+ // Ðàçìåðû
+ gTriggers[i].Width := utils.readWord(st);
+ gTriggers[i].Height := utils.readWord(st);
+ // Âêëþ÷åí ëè òðèããåð
+ gTriggers[i].Enabled := utils.readBool(st);
+ // Òèï àêòèâàöèè òðèããåðà
+ gTriggers[i].ActivateType := utils.readByte(st);
+ // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè
+ gTriggers[i].Keys := utils.readByte(st);
+ // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ
+ gTriggers[i].TexturePanelGUID := utils.readLongInt(st);
+ // Òèï ýòîé ïàíåëè
+ //Mem.ReadWord(gTriggers[i].TexturePanelType);
+ // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+ gTriggers[i].trigPanelGUID := utils.readLongInt(st);
+ // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè
+ gTriggers[i].TimeOut := utils.readWord(st);
+ // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð
+ gTriggers[i].ActivateUID := utils.readWord(st);
+ // Ñïèñîê UID-îâ îáúåêòîâ, êîòîðûå íàõîäèëèñü ïîä âîçäåéñòâèåì
+ actCount := utils.readLongInt(st);
+ if (actCount < 0) or (actCount > 1024*1024) then raise XStreamError.Create('invalid activated object count');
+ if (actCount > 0) then
begin
begin
- raise EBinSizeError.Create('g_Triggers_LoadState: Wrong TriggerData Size');
- end;
- Trig.Data := TTriggerData(p^);
- // Ñîçäàåì òðèããåð:
- i := g_Triggers_Create(Trig);
- // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
- Mem.ReadInt(gTriggers[i].X);
- Mem.ReadInt(gTriggers[i].Y);
- // Ðàçìåðû:
- Mem.ReadWord(gTriggers[i].Width);
- Mem.ReadWord(gTriggers[i].Height);
- // Âêëþ÷åí ëè òðèããåð:
- Mem.ReadBoolean(gTriggers[i].Enabled);
- // Òèï àêòèâàöèè òðèããåðà:
- Mem.ReadByte(gTriggers[i].ActivateType);
- // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè:
- Mem.ReadByte(gTriggers[i].Keys);
- // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ:
- Mem.ReadInt(gTriggers[i].TexturePanel);
- // Òèï ýòîé ïàíåëè:
- Mem.ReadWord(gTriggers[i].TexturePanelType);
- // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
- Mem.ReadWord(gTriggers[i].TimeOut);
- // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
- Mem.ReadWord(gTriggers[i].ActivateUID);
- // Ñïèñîê UID-îâ îáúåêòîâ, êîòîðûå íàõîäèëèñü ïîä âîçäåéñòâèåì:
- Mem.ReadInt(act_count);
- if act_count > 0 then
- begin
- SetLength(gTriggers[i].Activators, act_count);
- for j := 0 to act_count-1 do
+ SetLength(gTriggers[i].Activators, actCount);
+ for j := 0 to actCount-1 do
begin
// UID îáúåêòà
begin
// UID îáúåêòà
- Mem.ReadWord(gTriggers[i].Activators[j].UID);
+ gTriggers[i].Activators[j].UID := utils.readWord(st);
// Âðåìÿ îæèäàíèÿ
// Âðåìÿ îæèäàíèÿ
- Mem.ReadWord(gTriggers[i].Activators[j].TimeOut);
+ gTriggers[i].Activators[j].TimeOut := utils.readWord(st);
end;
end;
end;
end;
- // Ñòîèò ëè èãðîê â îáëàñòè òðèããåðà:
- Mem.ReadBoolean(gTriggers[i].PlayerCollide);
- // Âðåìÿ äî çàêðûòèÿ äâåðè:
- Mem.ReadInt(gTriggers[i].DoorTime);
- // Çàäåðæêà àêòèâàöèè:
- Mem.ReadInt(gTriggers[i].PressTime);
- // Ñ÷åò÷èê íàæàòèé:
- Mem.ReadInt(gTriggers[i].PressCount);
- // Ñïàâíåð àêòèâåí:
- Mem.ReadBoolean(gTriggers[i].AutoSpawn);
- // Çàäåðæêà ñïàâíåðà:
- Mem.ReadInt(gTriggers[i].SpawnCooldown);
- // Ñ÷åò÷èê ñîçäàíèÿ îáúåêòîâ:
- Mem.ReadInt(gTriggers[i].SpawnedCount);
- // Ñêîëüêî ðàç ïðîèãðàí çâóê:
- Mem.ReadInt(gTriggers[i].SoundPlayCount);
- // Ïðîèãðûâàåòñÿ ëè çâóê?
- Mem.ReadBoolean(b);
+ // Ñòîèò ëè èãðîê â îáëàñòè òðèããåðà
+ gTriggers[i].PlayerCollide := utils.readBool(st);
+ // Âðåìÿ äî çàêðûòèÿ äâåðè
+ gTriggers[i].DoorTime := utils.readLongInt(st);
+ // Çàäåðæêà àêòèâàöèè
+ gTriggers[i].PressTime := utils.readLongInt(st);
+ // Ñ÷åò÷èê íàæàòèé
+ gTriggers[i].PressCount := utils.readLongInt(st);
+ // Ñïàâíåð àêòèâåí
+ gTriggers[i].AutoSpawn := utils.readBool(st);
+ // Çàäåðæêà ñïàâíåðà
+ gTriggers[i].SpawnCooldown := utils.readLongInt(st);
+ // Ñ÷åò÷èê ñîçäàíèÿ îáúåêòîâ
+ gTriggers[i].SpawnedCount := utils.readLongInt(st);
+ // Ñêîëüêî ðàç ïðîèãðàí çâóê
+ gTriggers[i].SoundPlayCount := utils.readLongInt(st);
+ // Ïðîèãðûâàåòñÿ ëè çâóê?
+ b := utils.readBool(st);
if b then
begin
if b then
begin
- // Ïîçèöèÿ ïðîèãðûâàíèÿ çâóêà:
- Mem.ReadDWORD(dw);
- // Ãðîìêîñòü çâóêà:
- Mem.ReadSingle(vol);
- // Ñòåðåî ñìåùåíèå çâóêà:
- Mem.ReadSingle(pan);
- // Çàïóñêàåì çâóê, åñëè åñòü:
- if gTriggers[i].Sound <> nil then
+ // Ïîçèöèÿ ïðîèãðûâàíèÿ çâóêà
+ dw := utils.readLongWord(st);
+ // Ãðîìêîñòü çâóêà
+ //Mem.ReadSingle(vol);
+ st.ReadBuffer(vol, sizeof(vol)); // sorry
+ // Ñòåðåî ñìåùåíèå çâóêà
+ //Mem.ReadSingle(pan);
+ st.ReadBuffer(pan, sizeof(pan)); // sorry
+ // Çàïóñêàåì çâóê, åñëè åñòü
+ if (gTriggers[i].Sound <> nil) then
begin
gTriggers[i].Sound.PlayPanVolume(pan, vol);
gTriggers[i].Sound.Pause(True);
gTriggers[i].Sound.SetPosition(dw);
end
end;
begin
gTriggers[i].Sound.PlayPanVolume(pan, vol);
gTriggers[i].Sound.Pause(True);
gTriggers[i].Sound.SetPosition(dw);
end
end;
+ // uservars
+ gTriggers[i].userVars.Free();
+ gTriggers[i].userVars := nil;
+ uvcount := utils.readLongInt(st);
+ if (uvcount < 0) or (uvcount > 1024*1024) then raise XStreamError.Create('invalid number of user vars in trigger');
+ if (uvcount > 0) then
+ begin
+ gTriggers[i].userVars := THashStrVariant.Create();
+ vv := Unassigned;
+ while (uvcount > 0) do
+ begin
+ Dec(uvcount);
+ uvname := utils.readStr(st);
+ vt := utils.readLongInt(st);
+ case vt of
+ varString: begin ustr := utils.readStr(st); vv := ustr; end;
+ varBoolean: begin ubool := utils.readBool(st); vv := ubool; end;
+ varShortInt: begin uint := utils.readLongInt(st); vv := ShortInt(uint); end;
+ varSmallint: begin uint := utils.readLongInt(st); vv := SmallInt(uint); end;
+ varInteger: begin uint := utils.readLongInt(st); vv := LongInt(uint); end;
+ varByte: begin uint := utils.readLongInt(st); vv := Byte(uint); end;
+ varWord: begin uint := utils.readLongInt(st); vv := Word(uint); end;
+ varLongWord: begin uint := utils.readLongInt(st); vv := LongWord(uint); end;
+ else raise Exception.CreateFmt('cannot load uservar ''%s''', [uvname]);
+ end;
+ gTriggers[i].userVars.put(uvname, vv);
+ end;
+ end;
end;
end;
end;
end;
+
end.
end.