DEADSOFTWARE

cleanup: remove g_main.pas
[d2df-sdl.git] / src / game / g_weapons.pas
index 632cb1344c3e4728f37478e4e683e1d1ac652cb0..81767e653f03be80e7d7a5b58fb7dd0970db4413 100644 (file)
@@ -20,7 +20,7 @@ interface
 
 uses
   SysUtils, Classes, mempool,
-  g_textures, g_basic, e_graphics, g_phys, xprofiler;
+  g_textures, g_basic, g_phys, xprofiler;
 
 
 type
@@ -51,7 +51,7 @@ function g_Weapon_Hit(obj: PObj; d: Integer; SpawnerUID: Word; t: Byte; HitCorps
 function g_Weapon_HitUID(UID: Word; d: Integer; SpawnerUID: Word; t: Byte): Boolean;
 function g_Weapon_CreateShot(I: Integer; ShotType: Byte; Spawner, TargetUID: Word; X, Y, XV, YV: Integer): LongWord;
 
-procedure g_Weapon_gun(const x, y, xd, yd, v, dmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean);
+procedure g_Weapon_gun(const x, y, xd, yd, v, indmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean);
 procedure g_Weapon_punch(x, y: Integer; d, SpawnerUID: Word);
 function g_Weapon_chainsaw(x, y: Integer; d, SpawnerUID: Word): Integer;
 procedure g_Weapon_rocket(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1; Silent: Boolean = False);
@@ -72,8 +72,8 @@ procedure g_Weapon_dshotgun(x, y, xd, yd: Integer; SpawnerUID: Word; Silent: Boo
 
 function g_Weapon_Explode(X, Y: Integer; rad: Integer; SpawnerUID: Word): Boolean;
 procedure g_Weapon_BFG9000(X, Y: Integer; SpawnerUID: Word);
+procedure g_Weapon_PreUpdate();
 procedure g_Weapon_Update();
-procedure g_Weapon_Draw();
 function g_Weapon_Danger(UID: Word; X, Y: Integer; Width, Height: Word; Time: Byte): Boolean;
 procedure g_Weapon_DestroyShot(I: Integer; X, Y: Integer; Loud: Boolean = True);
 
@@ -113,7 +113,7 @@ var
 implementation
 
 uses
-  Math, g_map, g_player, g_gfx, g_sound, g_main, g_panel,
+  Math, g_map, g_player, g_gfx, g_sound, g_panel,
   g_console, g_options, g_game,
   g_triggers, MAPDEF, e_log, g_monsters, g_saveload,
   g_language, g_netmsg, g_grid,
@@ -526,7 +526,7 @@ begin
               g_TraceVector(X, Y, Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2),
                             Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)) then
           begin
-            Damage(50, 0, 0);
+            Damage(50, SpawnerUID, 0, 0);
             g_Weapon_BFGHit(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2),
                             Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2));
           end;
@@ -737,6 +737,8 @@ begin
     end;
   end;
 
+  Shots[find_id].Obj.oldX := X;
+  Shots[find_id].Obj.oldY := Y;
   Shots[find_id].Obj.X := X;
   Shots[find_id].Obj.Y := Y;
   Shots[find_id].Obj.Vel.X := XV;
@@ -762,6 +764,8 @@ begin
   if a = 0 then
     a := 1;
 
+  Shots[i].Obj.oldX := x;
+  Shots[i].Obj.oldY := y;
   Shots[i].Obj.X := x;
   Shots[i].Obj.Y := y;
   Shots[i].Obj.Vel.X := (xd*s) div a;
@@ -871,8 +875,8 @@ begin
            g_Obj_Collide(obj, @gCorpses[i].Obj) then
         begin
           // Ðàñïèëèâàåì òðóï:
-          gCorpses[i].Damage(d, (obj^.Vel.X+obj^.Accel.X) div 4,
-                                (obj^.Vel.Y+obj^.Accel.Y) div 4);
+          gCorpses[i].Damage(d, SpawnerUID, (obj^.Vel.X+obj^.Accel.X) div 4,
+                                            (obj^.Vel.Y+obj^.Accel.Y) div 4);
           Result := 1;
         end;
   end;
@@ -888,10 +892,16 @@ begin
         Exit;
       end;
 
-      if PlayerHit() then
+      // È â êîíöå èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî
+      // (èëè ñíàðÿä îò ìîíñòðà, èëè friendlyfire, èëè friendly_hit_projectile)
+      if (g_GetUIDType(SpawnerUID) <> UID_PLAYER) or
+         LongBool(gGameSettings.Options and (GAME_OPTION_TEAMDAMAGE or GAME_OPTION_TEAMHITPROJECTILE)) then
       begin
-        Result := 1;
-        Exit;
+        if PlayerHit() then
+        begin
+          Result := 1;
+          Exit;
+        end;
       end;
     end;
 
@@ -929,11 +939,15 @@ begin
         Exit;
       end;
 
-      // È â êîíöå ñâîèõ èãðîêîâ
-      if PlayerHit(1) then
+      // È â êîíöå ñâîèõ èãðîêîâ, íî òîëüêî åñëè ïîëîæåíî
+      // (èëè friendlyfire, èëè friendly_hit_projectile)
+      if LongBool(gGameSettings.Options and (GAME_OPTION_TEAMDAMAGE or GAME_OPTION_TEAMHITPROJECTILE)) then
       begin
-        Result := 1;
-        Exit;
+        if PlayerHit(1) then
+        begin
+          Result := 1;
+          Exit;
+        end;
       end;
     end;
 
@@ -1045,7 +1059,7 @@ begin
             mm := Max(abs(dx), abs(dy));
             if mm = 0 then mm := 1;
 
-            Damage(Round(100*(rad-m)/rad), (dx*10) div mm, (dy*10) div mm);
+            Damage(Round(100*(rad-m)/rad), SpawnerUID, (dx*10) div mm, (dy*10) div mm);
           end;
         end;
 
@@ -1383,18 +1397,30 @@ end;
 
 
 //!!!FIXME!!!
-procedure g_Weapon_gun (const x, y, xd, yd, v, dmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean);
+procedure g_Weapon_gun (const x, y, xd, yd, v, indmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean);
 var
   x0, y0: Integer;
   x2, y2: Integer;
   xi, yi: Integer;
   wallDistSq: Integer = $3fffffff;
+  spawnerPlr: TPlayer = nil;
+  dmg: Integer;
 
   function doPlayerHit (idx: Integer; hx, hy: Integer): Boolean;
   begin
     result := false;
     if (idx < 0) or (idx > High(gPlayers)) then exit;
     if (gPlayers[idx] = nil) or not gPlayers[idx].alive then exit;
+    if (spawnerPlr <> nil) then
+    begin
+      if ((gGameSettings.Options and (GAME_OPTION_TEAMHITTRACE or GAME_OPTION_TEAMDAMAGE)) = 0) and
+         (spawnerPlr.Team <> TEAM_NONE) and (spawnerPlr.Team = gPlayers[idx].Team) then
+      begin
+        if (spawnerPlr <> gPlayers[idx]) and ((gGameSettings.Options and GAME_OPTION_TEAMABSORBDAMAGE) = 0) then
+          dmg := Max(1, dmg div 2);
+        exit;
+      end;
+    end;
     result := HitPlayer(gPlayers[idx], dmg, (xi*v)*10, (yi*v)*10-3, SpawnerUID, HIT_SOME);
     if result and (v <> 0) then gPlayers[idx].Push((xi*v), (yi*v));
     {$IF DEFINED(D2F_DEBUG)}
@@ -1487,6 +1513,11 @@ begin
 
   if (xd = 0) and (yd = 0) then exit;
 
+  if (g_GetUIDType(SpawnerUID) = UID_PLAYER) then
+    spawnerPlr := g_Player_Get(SpawnerUID);
+
+  dmg := indmg;
+
   //wgunMonHash.reset(); //FIXME: clear hash on level change
   wgunHitHeap.clear();
   wgunHitTimeUsed := 0;
@@ -2093,6 +2124,19 @@ begin
   end;
 end;
 
+procedure g_Weapon_PreUpdate();
+var
+  i: Integer;
+begin
+  if Shots = nil then Exit;
+  for i := 0 to High(Shots) do
+    if Shots[i].ShotType <> 0 then
+    begin
+      Shots[i].Obj.oldX := Shots[i].Obj.X;
+      Shots[i].Obj.oldY := Shots[i].Obj.Y;
+    end;
+end;
+
 procedure g_Weapon_Update();
 var
   i, a, h, cx, cy, oldvx, oldvy, tf: Integer;
@@ -2499,58 +2543,6 @@ begin
   end;
 end;
 
-procedure g_Weapon_Draw();
-var
-  i: Integer;
-  a: SmallInt;
-  p: TDFPoint;
-begin
-  if Shots = nil then
-    Exit;
-
-  for i := 0 to High(Shots) do
-    if Shots[i].ShotType <> 0 then
-      with Shots[i] do
-      begin
-        if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) or
-           (Shots[i].ShotType = WEAPON_BARON_FIRE) or
-           (Shots[i].ShotType = WEAPON_MANCUB_FIRE) or
-           (Shots[i].ShotType = WEAPON_SKEL_FIRE) then
-          a := -GetAngle2(Obj.Vel.X, Obj.Vel.Y)
-        else
-          a := 0;
-
-        p.X := Obj.Rect.Width div 2;
-        p.Y := Obj.Rect.Height div 2;
-
-        if Animation <> nil then
-          begin
-            if (Shots[i].ShotType = WEAPON_BARON_FIRE) or
-               (Shots[i].ShotType = WEAPON_MANCUB_FIRE) or
-               (Shots[i].ShotType = WEAPON_SKEL_FIRE) then
-              Animation.DrawEx(Obj.X, Obj.Y, TMirrorType.None, p, a)
-            else
-              Animation.Draw(Obj.X, Obj.Y, TMirrorType.None);
-          end
-        else if TextureID <> 0 then
-          begin
-            if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) then
-              e_DrawAdv(TextureID, Obj.X, Obj.Y, 0, True, False, a, @p, TMirrorType.None)
-            else if (Shots[i].ShotType <> WEAPON_FLAMETHROWER) then
-              e_Draw(TextureID, Obj.X, Obj.Y, 0, True, False);
-          end;
-
-          if g_debug_Frames then
-          begin
-            e_DrawQuad(Obj.X+Obj.Rect.X,
-                       Obj.Y+Obj.Rect.Y,
-                       Obj.X+Obj.Rect.X+Obj.Rect.Width-1,
-                       Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1,
-                       0, 255, 0);
-          end;
-      end;
-end;
-
 function g_Weapon_Danger(UID: Word; X, Y: Integer; Width, Height: Word; Time: Byte): Boolean;
 var
   a: Integer;