DEADSOFTWARE

no more old mapreader: use textmap reader both for text and for binary maps
[d2df-sdl.git] / src / game / g_triggers.pas
index 29ea42ee3ddf3b1702d8a0569a4a490600ee6672..c327fdb55c2afcd0257ec015562191cdcc0aade1 100644 (file)
@@ -19,7 +19,7 @@ unit g_triggers;
 interface
 
 uses
-  MAPSTRUCT, e_graphics, MAPDEF, g_basic, g_sound,
+  MAPDEF, e_graphics, g_basic, g_sound,
   BinEditor;
 
 type
@@ -101,7 +101,7 @@ 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;
+  g_options, g_net, g_netmsg, utils;
 
 const
   TRIGGER_SIGNATURE = $52475254; // 'TRGR'
@@ -211,13 +211,10 @@ var
   a, b, c: Integer;
   wx, wy, wh, ww: Integer;
 
-  function monsDamage (monidx: Integer; mon: TMonster): Boolean;
+  function monsDamage (mon: TMonster): Boolean;
   begin
     result := false; // don't stop
-    if (mon <> nil) and mon.Live and g_Obj_Collide(wx, wy, ww, wh, @mon.Obj) then
-    begin
-      mon.Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
-    end;
+    if g_Obj_Collide(wx, wy, ww, wh, @mon.Obj) then mon.Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
   end;
 
 begin
@@ -248,7 +245,8 @@ begin
               gPlayers[a].Collide(X, Y, Width, Height) then
             gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
 
-      g_Mons_ForEach(monsDamage);
+      //g_Mons_ForEach(monsDamage);
+      g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage);
 
       if not Enabled then g_Map_EnableWall(PanelID);
     end;
@@ -304,7 +302,8 @@ begin
             gPlayers[a].Collide(X, Y, Width, Height) then
               gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
 
-        g_Mons_ForEach(monsDamage);
+        //g_Mons_ForEach(monsDamage);
+        g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage);
         (*
         if gMonsters <> nil then
           for a := 0 to High(gMonsters) do
@@ -648,7 +647,7 @@ begin
 
       dx := dx + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
       dy := dy + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
-      
+
       tr_SpawnShot(Data.ShotType, wx, wy, dx, dy, Data.ShotSound, TargetUID);
     end
     else
@@ -986,10 +985,10 @@ var
   it: PItem;
   mon: TMonster;
 
-  function monsShotTarget (monidx: Integer; mon: TMonster): Boolean;
+  function monsShotTarget (mon: TMonster): Boolean;
   begin
     result := false; // don't stop
-    if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
+    if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
     begin
       xd := mon.GameX + mon.Obj.Rect.Width div 2;
       yd := mon.GameY + mon.Obj.Rect.Height div 2;
@@ -998,10 +997,10 @@ var
     end;
   end;
 
-  function monsShotTargetMonPlr (monidx: Integer; mon: TMonster): Boolean;
+  function monsShotTargetMonPlr (mon: TMonster): Boolean;
   begin
     result := false; // don't stop
-    if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
+    if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
     begin
       xd := mon.GameX + mon.Obj.Rect.Width div 2;
       yd := mon.GameY + mon.Obj.Rect.Height div 2;
@@ -1010,10 +1009,10 @@ var
     end;
   end;
 
-  function monShotTargetPlrMon (monidx: Integer; mon: TMonster): Boolean;
+  function monShotTargetPlrMon (mon: TMonster): Boolean;
   begin
     result := false; // don't stop
-    if (mon <> nil) and mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
+    if mon.Live and tr_ShotAimCheck(Trigger, @(mon.Obj)) then
     begin
       xd := mon.GameX + mon.Obj.Rect.Width div 2;
       yd := mon.GameY + mon.Obj.Rect.Height div 2;
@@ -1930,7 +1929,8 @@ begin
 
           case Data.ShotTarget of
             TRIGGER_SHOT_TARGET_MON: // monsters
-              g_Mons_ForEach(monsShotTarget);
+              //TODO: accelerate this!
+              g_Mons_ForEachAlive(monsShotTarget);
 
             TRIGGER_SHOT_TARGET_PLR: // players
               if gPlayers <> nil then
@@ -1972,7 +1972,8 @@ begin
 
             TRIGGER_SHOT_TARGET_MONPLR: // monsters then players
             begin
-              g_Mons_ForEach(monsShotTargetMonPlr);
+              //TODO: accelerate this!
+              g_Mons_ForEachAlive(monsShotTargetMonPlr);
 
               if (TargetUID = 0) and (gPlayers <> nil) then
                 for idx := Low(gPlayers) to High(gPlayers) do
@@ -1998,7 +1999,11 @@ begin
                     TargetUID := gPlayers[idx].UID;
                     break;
                   end;
-              if TargetUID = 0 then g_Mons_ForEach(monShotTargetPlrMon);
+              if TargetUID = 0 then
+              begin
+                //TODO: accelerate this!
+                g_Mons_ForEachAlive(monShotTargetPlrMon);
+              end;
             end;
 
             else begin
@@ -2191,29 +2196,34 @@ begin
   Result := find_id;
 end;
 
+
+// sorry; grid doesn't support recursive queries, so we have to do this
+type
+  TSimpleMonsterList = specialize TSimpleList<TMonster>;
+
+var
+  tgMonsList: TSimpleMonsterList = nil;
+
 procedure g_Triggers_Update();
 var
   a, b, i: Integer;
   Affected: array of Integer;
 
-  {function monsNear (monidx: Integer; mon: TMonster): Boolean;
-  begin
-    result := false; // don't stop
-    if mon.Collide(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height) then
-    begin
-      gTriggers[a].ActivateUID := mon.UID;
-      ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
-    end;
-  end;}
-
-  function monsNear (monidx: Integer; mon: TMonster): Boolean;
+  function monsNear (mon: TMonster): Boolean;
   begin
     result := false; // don't stop
+    {
     gTriggers[a].ActivateUID := mon.UID;
     ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+    }
+    tgMonsList.append(mon);
   end;
 
+var
+  mon: TMonster;
 begin
+  if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create();
+
   if gTriggers = nil then
     Exit;
   SetLength(Affected, 0);
@@ -2448,7 +2458,15 @@ begin
              (TimeOut = 0) and (Keys = 0) then // Åñëè íå íóæíû êëþ÷è
           begin
             //g_Mons_ForEach(monsNear);
+            //Alive?!
+            tgMonsList.reset();
             g_Mons_ForEachAt(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height, monsNear);
+            for mon in tgMonsList do
+            begin
+              gTriggers[a].ActivateUID := mon.UID;
+              ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+            end;
+            tgMonsList.reset(); // just in case
           end;
 
           // "Ìîíñòðîâ íåò"