index edafecc999a259e828799a9e1d51d3bd5d59603e..6698288c33cda673ec4fe9129256171494b1fc1c 100644 (file)
--- a/src/game/g_triggers.pas
+++ b/src/game/g_triggers.pas
UID: Word;
TimeOut: Word;
end;
+ PTrigger = ^TTrigger;
TTrigger = record
+ public
ID: DWORD;
ClientID: DWORD;
TriggerType: Byte;
ShotAmmoCount: Word;
ShotReloadTime: Integer;
+ mapId: AnsiString; // trigger id, from map
+ mapIndex: Integer; // index in fields['trigger'], used in save/load
//trigShotPanelId: Integer;
trigPanelId: Integer;
//TrigData: TTriggerData;
trigData: TDynRecord; // triggerdata; owned by trigger
+ public
+ function trigCenter (): TDFPoint; inline;
+
+ public
property trigShotPanelId: Integer read trigPanelId write trigPanelId;
end;
-function g_Triggers_Create(Trigger: TTrigger): DWORD;
+function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD;
procedure g_Triggers_Update();
procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0);
function g_Triggers_PressR(X, Y: Integer; Width, Height: Word; UID: Word;
g_player, g_map, Math, g_gfx, g_game, g_textures,
g_console, g_monsters, g_items, g_phys, g_weapons,
wadreader, g_main, SysUtils, e_log, g_language,
- g_options, g_net, g_netmsg, utils;
+ g_options, g_net, g_netmsg, utils, xparser;
const
- TRIGGER_SIGNATURE = $52475254; // 'TRGR'
+ TRIGGER_SIGNATURE = $58475254; // 'TRGX'
TRAP_DAMAGE = 1000;
+
+function TTrigger.trigCenter (): TDFPoint; inline;
+begin
+ result := TDFPoint.Create(x+width div 2, y+height div 2);
+end;
+
+
function FindTrigger(): DWORD;
var
i: Integer;
begin
- if gTriggers <> nil then
- for i := 0 to High(gTriggers) do
- if gTriggers[i].TriggerType = TRIGGER_NONE then
- begin
- Result := i;
- Exit;
- end;
+ for i := 0 to High(gTriggers) do
+ begin
+ if gTriggers[i].TriggerType = TRIGGER_NONE then begin result := i; exit; end;
+ end;
- if gTriggers = nil then
+ if (gTriggers = nil) then
begin
SetLength(gTriggers, 8);
- Result := 0;
+ result := 0;
end
else
begin
- Result := High(gTriggers) + 1;
- SetLength(gTriggers, Length(gTriggers) + 8);
+ result := Length(gTriggers);
+ SetLength(gTriggers, result+8);
+ for i := result to High(gTriggers) do gTriggers[i].TriggerType := TRIGGER_NONE;
end;
end;
+
function tr_CloseDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
var
a, b, c: Integer;
g_Map_SwitchTexture(Trigger.TexturePanelType, Trigger.TexturePanel, IfThen(animonce, 2, 1));
end;
-function g_Triggers_Create(Trigger: TTrigger): DWORD;
+
+function g_Triggers_CreateWithMapIndex (Trigger: TTrigger; arridx, mapidx: Integer): DWORD;
+var
+ triggers: TDynField;
+begin
+ triggers := gCurrentMap['trigger'];
+ if (triggers = nil) then raise Exception.Create('LOAD: map has no triggers');
+ if (mapidx < 0) or (mapidx >= triggers.count) then raise Exception.Create('LOAD: invalid map trigger index');
+ Trigger.trigData := triggers.item[mapidx];
+ if (Trigger.trigData = nil) then raise Exception.Create('LOAD: internal error in trigger loader');
+ Trigger.mapId := Trigger.trigData.id;
+ Trigger.mapIndex := mapidx;
+ if (Trigger.trigData.trigRec <> nil) then
+ begin
+ Trigger.trigData := Trigger.trigData.trigRec.clone();
+ end
+ else
+ begin
+ Trigger.trigData := nil;
+ end;
+ result := g_Triggers_Create(Trigger, arridx);
+end;
+
+
+function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD;
var
find_id: DWORD;
- fn, mapw: String;
+ fn, mapw: AnsiString;
+ f, olen: Integer;
begin
// Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà:
if (Trigger.TriggerType = TRIGGER_EXIT) and
if Trigger.TriggerType = TRIGGER_SECRET then
gSecretsCount := gSecretsCount + 1;
- find_id := FindTrigger();
+ if (forceInternalIndex < 0) then
+ begin
+ find_id := FindTrigger();
+ end
+ else
+ begin
+ olen := Length(gTriggers);
+ if (forceInternalIndex >= olen) then
+ begin
+ SetLength(gTriggers, forceInternalIndex+1);
+ for f := olen to High(gTriggers) do gTriggers[f].TriggerType := TRIGGER_NONE;
+ end;
+ find_id := DWORD(forceInternalIndex);
+ end;
gTriggers[find_id] := Trigger;
+ //e_LogWritefln('created trigger with map index %s, findid=%s (%s)', [Trigger.mapIndex, find_id, Trigger.mapId]);
+
+ {
writeln('trigger #', find_id, ': pos=(', Trigger.x, ',', Trigger.y, ')-(', Trigger.width, 'x', Trigger.height, ')',
'; TexturePanel=', Trigger.TexturePanel,
'; TexturePanelType=', Trigger.TexturePanelType,
'; trigPanelId=', Trigger.trigPanelId,
'; trigShotPanelId=', Trigger.trigShotPanelId
);
+ }
with gTriggers[find_id] do
begin
begin
for a := 0 to High(gTriggers) do
begin
- gTriggers[a].trigData.Free();
if (gTriggers[a].TriggerType = TRIGGER_SOUND) then
begin
if g_Sound_Exists(gTriggers[a].trigData.trigSoundName) then
begin
SetLength(gTriggers[a].Activators, 0);
end;
+ gTriggers[a].trigData.Free();
end;
gTriggers := nil;
dw: DWORD;
sg: Single;
b: Boolean;
- //p: Pointer;
begin
-// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ:
- count := 0;
- if gTriggers <> nil then
- for i := 0 to High(gTriggers) do
- count := count + 1;
+ // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ
+ count := Length(gTriggers);
Mem := TBinMemoryWriter.Create((count+1) * 200);
-// Êîëè÷åñòâî òðèããåðîâ:
+ // Êîëè÷åñòâî òðèããåðîâ:
Mem.WriteInt(count);
- if count = 0 then
- Exit;
+ //e_LogWritefln('saving %s triggers (count=%s)', [Length(gTriggers), count]);
+
+ if count = 0 then exit;
for i := 0 to High(gTriggers) do
begin
// Ñèãíàòóðà òðèããåðà:
- dw := TRIGGER_SIGNATURE; // 'TRGR'
+ dw := TRIGGER_SIGNATURE; // 'TRGX'
Mem.WriteDWORD(dw);
// Òèï òðèããåðà:
Mem.WriteByte(gTriggers[i].TriggerType);
- // Ñïåöèàëüíûå äàííûå òðèããåðà:
- //!!!FIXME!!!
+ if (gTriggers[i].TriggerType = TRIGGER_NONE) then continue; // empty one
+ // Ñïåöèàëüíûå äàííûå òðèããåðà: äà â æîïó, ïîòîì èç êàðòû îïÿòü âûòàùèì; ñîõðàíèì òîëüêî èíäåêñ
+ //e_LogWritefln('=== trigger #%s saved ===', [gTriggers[i].mapIndex]);
+ Mem.WriteInt(gTriggers[i].mapIndex);
//p := @gTriggers[i].Data;
//Mem.WriteMemory(p, SizeOf(TTriggerData));
// Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
Mem.WriteInt(gTriggers[i].TexturePanel);
// Òèï ýòîé ïàíåëè:
Mem.WriteWord(gTriggers[i].TexturePanelType);
+ // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+ Mem.WriteInt(gTriggers[i].trigPanelId);
// Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
Mem.WriteWord(gTriggers[i].TimeOut);
// UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
b: Boolean;
//p: Pointer;
Trig: TTrigger;
+ mapIndex: Integer;
+ //tw: TStrTextWriter;
begin
if Mem = nil then
Exit;
// Êîëè÷åñòâî òðèããåðîâ:
Mem.ReadInt(count);
- if count = 0 then
- Exit;
+ if (count = 0) then exit;
for a := 0 to count-1 do
begin
// Ñèãíàòóðà òðèããåðà:
Mem.ReadDWORD(dw);
- if dw <> TRIGGER_SIGNATURE then // 'TRGR'
+ if (dw <> TRIGGER_SIGNATURE) then // 'TRGX'
begin
raise EBinSizeError.Create('g_Triggers_LoadState: Wrong Trigger Signature');
end;
// Òèï òðèããåðà:
Mem.ReadByte(Trig.TriggerType);
- // Ñïåöèàëüíûå äàííûå òðèããåðà:
+ // Ñïåöèàëüíûå äàííûå òðèããåðà: èíäåêñ â gCurrentMap.field['triggers']
+ if (Trig.TriggerType = TRIGGER_NONE) then continue; // empty one
+ Mem.ReadInt(mapIndex);
//!!!FIXME!!!
{
Mem.ReadMemory(p, dw);
Trig.Data := TTriggerData(p^);
}
// Ñîçäàåì òðèããåð:
- i := g_Triggers_Create(Trig);
+ i := g_Triggers_CreateWithMapIndex(Trig, a, mapIndex);
+ {
+ if (gTriggers[i].trigData <> nil) then
+ begin
+ tw := TStrTextWriter.Create();
+ try
+ gTriggers[i].trigData.writeTo(tw);
+ e_LogWritefln('=== trigger #%s loaded ==='#10'%s'#10'---', [mapIndex, tw.str]);
+ finally
+ tw.Free();
+ end;
+ end;
+ }
// Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
Mem.ReadInt(gTriggers[i].X);
Mem.ReadInt(gTriggers[i].Y);
Mem.ReadInt(gTriggers[i].TexturePanel);
// Òèï ýòîé ïàíåëè:
Mem.ReadWord(gTriggers[i].TexturePanelType);
+ // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+ Mem.ReadInt(gTriggers[i].trigPanelId);
// Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
Mem.ReadWord(gTriggers[i].TimeOut);
// UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: