From 2b647061c5ce08e02c046c3ef8e0a31917cc28f3 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Fri, 1 Sep 2017 01:45:38 +0300 Subject: [PATCH] save/load seems to work now --- src/game/g_map.pas | 15 ++++- src/game/g_triggers.pas | 126 +++++++++++++++++++++++++++++----------- src/shared/xparser.pas | 42 ++++++++++++++ 3 files changed, 147 insertions(+), 36 deletions(-) diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 6b64d88..f2922d4 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -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; diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index 064b3b6..a1183e8 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -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 òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: diff --git a/src/shared/xparser.pas b/src/shared/xparser.pas index 3f1d1db..76ac3c0 100644 --- a/src/shared/xparser.pas +++ b/src/shared/xparser.pas @@ -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. -- 2.29.2