DEADSOFTWARE

removed some debug output
[d2df-sdl.git] / src / game / g_triggers.pas
index edafecc999a259e828799a9e1d51d3bd5d59603e..6698288c33cda673ec4fe9129256171494b1fc1c 100644 (file)
@@ -27,7 +27,9 @@ type
     UID:     Word;
     TimeOut: Word;
   end;
+  PTrigger = ^TTrigger;
   TTrigger = record
+  public
     ID:               DWORD;
     ClientID:         DWORD;
     TriggerType:      Byte;
@@ -60,16 +62,22 @@ type
     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;
@@ -107,36 +115,42 @@ uses
   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;
@@ -2083,10 +2097,35 @@ begin
     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
@@ -2103,9 +2142,25 @@ begin
   if Trigger.TriggerType = TRIGGER_SECRET then
     gSecretsCount := gSecretsCount + 1;
 
-  find_id := FindTrigger();
+  if (forceInternalIndex < 0) then
+  begin
+    find_id := FindTrigger();
+  end
+  else
+  begin
+    olen := Length(gTriggers);
+    if (forceInternalIndex >= olen) then
+    begin
+      SetLength(gTriggers, forceInternalIndex+1);
+      for f := olen to High(gTriggers) do gTriggers[f].TriggerType := TRIGGER_NONE;
+    end;
+    find_id := DWORD(forceInternalIndex);
+  end;
   gTriggers[find_id] := Trigger;
 
+  //e_LogWritefln('created trigger with map index %s, findid=%s (%s)', [Trigger.mapIndex, find_id, Trigger.mapId]);
+
+  {
   writeln('trigger #', find_id, ': pos=(', Trigger.x, ',', Trigger.y, ')-(', Trigger.width, 'x', Trigger.height, ')',
     '; TexturePanel=', Trigger.TexturePanel,
     '; TexturePanelType=', Trigger.TexturePanelType,
@@ -2116,6 +2171,7 @@ begin
     '; trigPanelId=', Trigger.trigPanelId,
     '; trigShotPanelId=', Trigger.trigShotPanelId
     );
+  }
 
   with gTriggers[find_id] do
   begin
@@ -2666,7 +2722,6 @@ var
 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
@@ -2679,6 +2734,7 @@ begin
     begin
       SetLength(gTriggers[a].Activators, 0);
     end;
+    gTriggers[a].trigData.Free();
   end;
 
   gTriggers := nil;
@@ -2692,31 +2748,30 @@ var
   dw: DWORD;
   sg: Single;
   b: Boolean;
-  //p: Pointer;
 begin
-// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ:
-  count := 0;
-  if gTriggers <> nil then
-    for i := 0 to High(gTriggers) do
-      count := count + 1;
+  // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ
+  count := Length(gTriggers);
 
   Mem := TBinMemoryWriter.Create((count+1) * 200);
 
-// Êîëè÷åñòâî òðèããåðîâ:
+  // Êîëè÷åñòâî òðèããåðîâ:
   Mem.WriteInt(count);
 
-  if count = 0 then
-    Exit;
+  //e_LogWritefln('saving %s triggers (count=%s)', [Length(gTriggers), count]);
+
+  if count = 0 then exit;
 
   for i := 0 to High(gTriggers) do
   begin
   // Ñèãíàòóðà òðèããåðà:
-    dw := TRIGGER_SIGNATURE; // 'TRGR'
+    dw := TRIGGER_SIGNATURE; // 'TRGX'
     Mem.WriteDWORD(dw);
   // Òèï òðèããåðà:
     Mem.WriteByte(gTriggers[i].TriggerType);
-  // Ñïåöèàëüíûå äàííûå òðèããåðà:
-  //!!!FIXME!!!
+    if (gTriggers[i].TriggerType = TRIGGER_NONE) then continue; // empty one
+  // Ñïåöèàëüíûå äàííûå òðèããåðà: äà â æîïó, ïîòîì èç êàðòû îïÿòü âûòàùèì; ñîõðàíèì òîëüêî èíäåêñ
+    //e_LogWritefln('=== trigger #%s saved ===', [gTriggers[i].mapIndex]);
+    Mem.WriteInt(gTriggers[i].mapIndex);
     //p := @gTriggers[i].Data;
     //Mem.WriteMemory(p, SizeOf(TTriggerData));
   // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
@@ -2735,6 +2790,8 @@ begin
     Mem.WriteInt(gTriggers[i].TexturePanel);
   // Òèï ýòîé ïàíåëè:
     Mem.WriteWord(gTriggers[i].TexturePanelType);
+  // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+    Mem.WriteInt(gTriggers[i].trigPanelId);
   // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
     Mem.WriteWord(gTriggers[i].TimeOut);
   // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
@@ -2795,6 +2852,8 @@ var
   b: Boolean;
   //p: Pointer;
   Trig: TTrigger;
+  mapIndex: Integer;
+  //tw: TStrTextWriter;
 begin
   if Mem = nil then
     Exit;
@@ -2804,20 +2863,21 @@ begin
 // Êîëè÷åñòâî òðèããåðîâ:
   Mem.ReadInt(count);
 
-  if count = 0 then
-    Exit;
+  if (count = 0) then exit;
 
   for a := 0 to count-1 do
   begin
   // Ñèãíàòóðà òðèããåðà:
     Mem.ReadDWORD(dw);
-    if dw <> TRIGGER_SIGNATURE then // 'TRGR'
+    if (dw <> TRIGGER_SIGNATURE) then // 'TRGX'
     begin
       raise EBinSizeError.Create('g_Triggers_LoadState: Wrong Trigger Signature');
     end;
   // Òèï òðèããåðà:
     Mem.ReadByte(Trig.TriggerType);
-  // Ñïåöèàëüíûå äàííûå òðèããåðà:
+  // Ñïåöèàëüíûå äàííûå òðèããåðà: èíäåêñ â gCurrentMap.field['triggers']
+    if (Trig.TriggerType = TRIGGER_NONE) then continue; // empty one
+    Mem.ReadInt(mapIndex);
   //!!!FIXME!!!
     {
     Mem.ReadMemory(p, dw);
@@ -2828,7 +2888,19 @@ begin
     Trig.Data := TTriggerData(p^);
     }
   // Ñîçäàåì òðèããåð:
-    i := g_Triggers_Create(Trig);
+    i := g_Triggers_CreateWithMapIndex(Trig, a, mapIndex);
+    {
+    if (gTriggers[i].trigData <> nil) then
+    begin
+      tw := TStrTextWriter.Create();
+      try
+        gTriggers[i].trigData.writeTo(tw);
+        e_LogWritefln('=== trigger #%s loaded ==='#10'%s'#10'---', [mapIndex, tw.str]);
+      finally
+        tw.Free();
+      end;
+    end;
+    }
   // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
     Mem.ReadInt(gTriggers[i].X);
     Mem.ReadInt(gTriggers[i].Y);
@@ -2845,6 +2917,8 @@ begin
     Mem.ReadInt(gTriggers[i].TexturePanel);
   // Òèï ýòîé ïàíåëè:
     Mem.ReadWord(gTriggers[i].TexturePanelType);
+  // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
+    Mem.ReadInt(gTriggers[i].trigPanelId);
   // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
     Mem.ReadWord(gTriggers[i].TimeOut);
   // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: