From 1e0f0d41e9a104418c9dc17598859b23b02d1e9c Mon Sep 17 00:00:00 2001
From: TerminalHash <lyashuk.voxx@gmail.com>
Date: Mon, 7 Jun 2021 21:36:38 +0300
Subject: [PATCH] Game: add damage absorption

---
 src/game/g_console.pas |  2 ++
 src/game/g_game.pas    |  5 +++++
 src/game/g_weapons.pas | 13 ++++++++++---
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/game/g_console.pas b/src/game/g_console.pas
index a6fa9c4..15497d9 100644
--- a/src/game/g_console.pas
+++ b/src/game/g_console.pas
@@ -1043,6 +1043,7 @@ begin
   AddCommand('g_friendlyfire', GameCVars);
   AddCommand('g_friendly_hit_trace', GameCVars);
   AddCommand('g_friendly_hit_projectile', GameCVars);
+  AddCommand('g_friendly_absorb_damage', GameCVars);
   AddCommand('g_weaponstay', GameCVars);
   AddCommand('g_allow_exit', GameCVars);
   AddCommand('g_dm_keys', GameCVars);
@@ -1160,6 +1161,7 @@ begin
   WhitelistCommand('g_friendlyfire');
   WhitelistCommand('g_friendly_hit_trace');
   WhitelistCommand('g_friendly_hit_projectile');
+  WhitelistCommand('g_friendly_absorb_damage');
   WhitelistCommand('g_weaponstay');
   WhitelistCommand('g_allow_exit');
   WhitelistCommand('g_dm_keys');
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 8271428..fefa3c0 100644
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
@@ -186,6 +186,7 @@ const
   GAME_OPTION_DMKEYS            = 128;
   GAME_OPTION_TEAMHITTRACE      = 256;
   GAME_OPTION_TEAMHITPROJECTILE = 512;
+  GAME_OPTION_TEAMABSORBDAMAGE = 1024;
 
   STATE_NONE        = 0;
   STATE_MENU        = 1;
@@ -5514,6 +5515,10 @@ begin
   begin
     ParseGameFlag(GAME_OPTION_TEAMDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
   end
+  else if cmd = 'g_friendly_absorb_damage' then
+ begin
+   ParseGameFlag(GAME_OPTION_TEAMABSORBDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
+ end
   else if cmd = 'g_friendly_hit_trace' then
   begin
     ParseGameFlag(GAME_OPTION_TEAMHITTRACE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas
index 4f91b9f..1dd4688 100644
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
@@ -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);
@@ -1398,13 +1398,14 @@ 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
@@ -1415,7 +1416,11 @@ var
     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
-        exit;
+          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));
@@ -1512,6 +1517,8 @@ begin
   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;
-- 
2.29.2