X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_triggers.pas;h=a1183e8e6899aacf51d23705851c21330fbdbcb1;hb=2b647061c5ce08e02c046c3ef8e0a31917cc28f3;hp=edafecc999a259e828799a9e1d51d3bd5d59603e;hpb=0c5455dd0914c9a9466668f3231c20ebb2f80522;p=d2df-sdl.git diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index edafecc..a1183e8 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -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 òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð: