DEADSOFTWARE

no more global `gItems[]` array; created DynTree for items (not used yet); also,...
[d2df-sdl.git] / src / game / g_triggers.pas
index 9ce8c0affc12cd9b8884fa381e40bd8c103ae392..7238c8046c4bec7b4a75921f1de6f47b38a1807c 100644 (file)
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *)
-{$MODE DELPHI}
+{$INCLUDE ../shared/a_modes.inc}
 unit g_triggers;
 
 interface
@@ -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_scripts;
+  g_options, g_net, g_netmsg;
 
 const
   TRIGGER_SIGNATURE = $52475254; // 'TRGR'
@@ -924,6 +924,23 @@ begin
   end;
 end;
 
+function tr_ShotAimCheck(var Trigger: TTrigger; Obj: PObj): Boolean;
+begin
+  result := false;
+  with Trigger do
+  begin
+    if TriggerType <> TRIGGER_SHOT then
+      Exit;
+    Result := (Data.ShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
+              or g_Obj_Collide(X, Y, Width, Height, Obj);
+    if Result and (Data.ShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
+      Result := g_TraceVector(Data.ShotPos.X,
+                              Data.ShotPos.Y,
+                              Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2),
+                              Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2));
+  end;
+end;
+
 function ActivateTrigger(var Trigger: TTrigger; actType: Byte): Boolean;
 var
   animonce: Boolean;
@@ -937,6 +954,7 @@ var
   Anim: TAnimation;
   UIDType: Byte;
   TargetUID: Word;
+  it: PItem;
 begin
   Result := False;
   if g_Game_IsClient then
@@ -1288,51 +1306,55 @@ begin
 
                 if Data.ItemMax > 0 then
                 begin
-                  gItems[iid].SpawnTrigger := ID;
+                  it := g_ItemByIdx(iid);
+                  it.SpawnTrigger := ID;
                   Inc(SpawnedCount);
                 end;
 
                 case Data.ItemEffect of
                   EFFECT_TELEPORT: begin
+                    it := g_ItemByIdx(iid);
                     if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
                     begin
                       Anim := TAnimation.Create(FramesID, False, 3);
                       g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.ItemPos.X, Data.ItemPos.Y);
-                      g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, Anim);
+                      g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
+                                     it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, Anim);
                       Anim.Free();
                     end;
                     if g_Game_IsServer and g_Game_IsNet then
-                      MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-32, 1,
+                      MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
+                                     it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, 1,
                                      NET_GFX_TELE);
                   end;
                   EFFECT_RESPAWN: begin
+                    it := g_ItemByIdx(iid);
                     if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
                     begin
                       Anim := TAnimation.Create(FramesID, False, 4);
                       g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.ItemPos.X, Data.ItemPos.Y);
-                      g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, Anim);
+                      g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16,
+                                     it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, Anim);
                       Anim.Free();
                     end;
                     if g_Game_IsServer and g_Game_IsNet then
-                      MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-16,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+(gItems[iid].Obj.Rect.Height div 2)-16, 1,
+                      MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16,
+                                     it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, 1,
                                      NET_GFX_RESPAWN);
                   end;
                   EFFECT_FIRE: begin
+                    it := g_ItemByIdx(iid);
                     if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
                     begin
                       Anim := TAnimation.Create(FramesID, False, 4);
                       g_Sound_PlayExAt('SOUND_FIRE', Data.ItemPos.X, Data.ItemPos.Y);
-                      g_GFX_OnceAnim(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, Anim);
+                      g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
+                                     it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, Anim);
                       Anim.Free();
                     end;
                     if g_Game_IsServer and g_Game_IsNet then
-                      MH_SEND_Effect(gItems[iid].Obj.X+gItems[iid].Obj.Rect.X+(gItems[iid].Obj.Rect.Width div 2)-32,
-                                     gItems[iid].Obj.Y+gItems[iid].Obj.Rect.Y+gItems[iid].Obj.Rect.Height-128, 1,
+                      MH_SEND_Effect(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
+                                     it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, 1,
                                      NET_GFX_FIRE);
                   end;
                 end;
@@ -1844,7 +1866,7 @@ begin
               if gMonsters <> nil then
                 for i := Low(gMonsters) to High(gMonsters) do
                   if (gMonsters[i] <> nil) and gMonsters[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
                   begin
                     xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
                     yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
@@ -1856,7 +1878,7 @@ begin
               if gPlayers <> nil then
                 for i := Low(gPlayers) to High(gPlayers) do
                   if (gPlayers[i] <> nil) and gPlayers[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
                   begin
                     xd := gPlayers[i].GameX + PLAYER_RECT_CX;
                     yd := gPlayers[i].GameY + PLAYER_RECT_CY;
@@ -1869,7 +1891,7 @@ begin
                 for i := Low(gPlayers) to High(gPlayers) do
                   if (gPlayers[i] <> nil) and gPlayers[i].Live and
                      (gPlayers[i].Team = TEAM_RED) and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
                   begin
                     xd := gPlayers[i].GameX + PLAYER_RECT_CX;
                     yd := gPlayers[i].GameY + PLAYER_RECT_CY;
@@ -1882,7 +1904,7 @@ begin
                 for i := Low(gPlayers) to High(gPlayers) do
                   if (gPlayers[i] <> nil) and gPlayers[i].Live and
                      (gPlayers[i].Team = TEAM_BLUE) and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
                   begin
                     xd := gPlayers[i].GameX + PLAYER_RECT_CX;
                     yd := gPlayers[i].GameY + PLAYER_RECT_CY;
@@ -1895,7 +1917,7 @@ begin
               if gMonsters <> nil then
                 for i := Low(gMonsters) to High(gMonsters) do
                   if (gMonsters[i] <> nil) and gMonsters[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
                   begin
                     xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
                     yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
@@ -1905,7 +1927,7 @@ begin
               if (TargetUID = 0) and (gPlayers <> nil) then
                 for i := Low(gPlayers) to High(gPlayers) do
                   if (gPlayers[i] <> nil) and gPlayers[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
                   begin
                     xd := gPlayers[i].GameX + PLAYER_RECT_CX;
                     yd := gPlayers[i].GameY + PLAYER_RECT_CY;
@@ -1919,7 +1941,7 @@ begin
               if gPlayers <> nil then
                 for i := Low(gPlayers) to High(gPlayers) do
                   if (gPlayers[i] <> nil) and gPlayers[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gPlayers[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gPlayers[i].Obj)) then
                   begin
                     xd := gPlayers[i].GameX + PLAYER_RECT_CX;
                     yd := gPlayers[i].GameY + PLAYER_RECT_CY;
@@ -1929,7 +1951,7 @@ begin
               if (TargetUID = 0) and (gMonsters <> nil) then
                 for i := Low(gMonsters) to High(gMonsters) do
                   if (gMonsters[i] <> nil) and gMonsters[i].Live and
-                     (Data.ShotAllMap or g_Obj_Collide(X, Y, Width, Height, @(gMonsters[i].Obj))) then
+                     tr_ShotAimCheck(Trigger, @(gMonsters[i].Obj)) then
                   begin
                     xd := gMonsters[i].GameX + gMonsters[i].Obj.Rect.Width div 2;
                     yd := gMonsters[i].GameY + gMonsters[i].Obj.Rect.Height div 2;
@@ -1945,7 +1967,8 @@ begin
             end;
           end;
 
-          if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) then
+          if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or
+            ((Data.ShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then
           begin
             Result := True;
             if (Data.ShotIntSight = 0) or
@@ -2001,13 +2024,6 @@ begin
           end;
           TimeOut := Data.FXWait;
         end;
-
-      TRIGGER_SCRIPT:
-        begin
-          g_Scripts_ProcExec(Data.SCRProc, [ID, ActivateUID, actType, Data.SCRArg], 'map');
-          TimeOut := 0;
-          Result := True;
-        end;
     end;
   end;