DEADSOFTWARE

save/load seems to work now
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Thu, 31 Aug 2017 22:45:38 +0000 (01:45 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Fri, 1 Sep 2017 00:33:55 +0000 (03:33 +0300)
src/game/g_map.pas
src/game/g_triggers.pas
src/shared/xparser.pas

index 6b64d8818ead94d6f3c925bd0dabfd68589e242f..f2922d4a9622c4f47d342a973a4e58b79d8b4694 100644 (file)
@@ -1190,7 +1190,7 @@ begin
   end;
 end;
 
-procedure CreateTrigger(Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word);
+procedure CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word);
 var
   _trigger: TTrigger;
 begin
@@ -1199,6 +1199,7 @@ begin
   with _trigger do
   begin
     mapId := Trigger.id;
+    mapIndex := amapIdx;
     X := Trigger.X;
     Y := Trigger.Y;
     Width := Trigger.Width;
@@ -1264,6 +1265,7 @@ procedure g_Map_ReAdd_DieTriggers();
   function monsDieTrig (mon: TMonster): Boolean;
   var
     a: Integer;
+    //tw: TStrTextWriter;
   begin
     result := false; // don't stop
     mon.ClearTriggers();
@@ -1272,6 +1274,15 @@ procedure g_Map_ReAdd_DieTriggers();
       if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
       begin
         //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a);
+        {
+        tw := TStrTextWriter.Create();
+        try
+          gTriggers[a].trigData.writeTo(tw);
+          e_LogWritefln('=== trigger #%s ==='#10'%s'#10'---', [a, tw.str]);
+        finally
+          tw.Free();
+        end;
+        }
         if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a);
       end;
     end;
@@ -1873,7 +1884,7 @@ begin
         else if (TriggersTable[trignum].ShotPanelIdx <> -1) then tgpid := TriggersTable[trignum].ShotPanelIdx
         else tgpid := -1;
         //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]);
-        CreateTrigger(rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c));
+        CreateTrigger(trignum, rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c));
       end;
     end;
 
index 064b3b6cebba673302668005eb580130f48e1789..a1183e8e6899aacf51d23705851c21330fbdbcb1 100644 (file)
@@ -63,6 +63,7 @@ type
     ShotReloadTime:   Integer;
 
     mapId: AnsiString; // trigger id, from map
+    mapIndex: Integer; // index in fields['trigger'], used in save/load
     //trigShotPanelId: Integer;
     trigPanelId: Integer;
 
@@ -76,7 +77,7 @@ type
     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;
@@ -114,10 +115,10 @@ 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;
 
 
@@ -131,26 +132,25 @@ 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;
@@ -2097,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
@@ -2117,9 +2142,24 @@ begin
   if Trigger.TriggerType = TRIGGER_SECRET then
     gSecretsCount := gSecretsCount + 1;
 
-  find_id := FindTrigger();
+  if (forceInternalIndex < 0) then
+  begin
+    find_id := FindTrigger();
+  end
+  else
+  begin
+    olen := Length(gTriggers);
+    if (forceInternalIndex >= olen) then
+    begin
+      SetLength(gTriggers, forceInternalIndex+1);
+      for f := olen to High(gTriggers) do gTriggers[f].TriggerType := TRIGGER_NONE;
+    end;
+    find_id := DWORD(forceInternalIndex);
+  end;
   gTriggers[find_id] := Trigger;
 
+  e_LogWritefln('created trigger with map index %s, findid=%s (%s)', [Trigger.mapIndex, find_id, Trigger.mapId]);
+
   {
   writeln('trigger #', find_id, ': pos=(', Trigger.x, ',', Trigger.y, ')-(', Trigger.width, 'x', Trigger.height, ')',
     '; TexturePanel=', Trigger.TexturePanel,
@@ -2708,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));
   // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
@@ -2751,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 òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
@@ -2811,6 +2852,8 @@ var
   b: Boolean;
   //p: Pointer;
   Trig: TTrigger;
+  mapIndex: Integer;
+  //tw: TStrTextWriter;
 begin
   if Mem = nil then
     Exit;
@@ -2820,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);
@@ -2844,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);
@@ -2861,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 òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
index 3f1d1db5b462a6ed9fc69fa7ff8284029e2270b6..76ac3c0165483ef90d4066904540d1eef5b7a2dd 100644 (file)
@@ -182,6 +182,20 @@ type
     procedure flush (); override;
   end;
 
+  TStrTextWriter = class(TTextWriter)
+  private
+    mStr: AnsiString;
+
+  protected
+    procedure putBuf (constref buf; len: SizeUInt); override;
+
+  public
+    constructor Create ();
+    destructor Destroy (); override;
+
+    property str: AnsiString read mStr;
+  end;
+
 
 implementation
 
@@ -732,4 +746,32 @@ begin
 end;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TStrTextWriter.Create ();
+begin
+  mStr := '';
+end;
+
+
+destructor TStrTextWriter.Destroy ();
+begin
+  mStr := '';
+  inherited;
+end;
+
+
+procedure TStrTextWriter.putBuf (constref buf; len: SizeUInt);
+var
+  st: AnsiString = '';
+begin
+  if (len > 0) then
+  begin
+    SetLength(st, Integer(len));
+    Move(buf, PChar(st)^, Integer(len));
+    mStr += st;
+    st := '';
+  end;
+end;
+
+
 end.