foxygit / doom Log in
commit 4ed8566a0b2803a9eb29216afaa48e57b86fc9e7
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sat Oct 28 19:30:59 2006 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sat Oct 28 19:30:59 2006 +0000

    Explicitly support dehacked patches that overflow the ammo[] array with
    an invalid ammo type, allowing weapons that decrease the max ammo of
    other weapons.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 743
---
 src/p_pspr.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/p_pspr.c b/src/p_pspr.c
index b29f7ae1..fe32c53f 100644
--- a/src/p_pspr.c
+++ b/src/p_pspr.c
@@ -541,6 +541,23 @@ A_Saw
     player->mo->flags |= MF_JUSTATTACKED;
 }

+// Doom does not check the bounds of the ammo array.  As a result,
+// it is possible to use an ammo type > 4 that overflows into the
+// maxammo array and affects that instead.  Through dehacked, for
+// example, it is possible to make a weapon that decreases the max
+// number of ammo for another weapon.  Emulate this.
+
+static void DecreaseAmmo(player_t *player, int ammonum, int amount)
+{
+    if (ammonum < NUMAMMO)
+    {
+        player->ammo[ammonum] -= amount;
+    }
+    else
+    {
+        player->maxammo[ammonum - NUMAMMO] -= amount;
+    }
+}


 //
@@ -551,7 +568,7 @@ A_FireMissile
 ( player_t*	player,
   pspdef_t*	psp )
 {
-    player->ammo[weaponinfo[player->readyweapon].ammo]--;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 1);
     P_SpawnPlayerMissile (player->mo, MT_ROCKET);
 }

@@ -564,7 +581,8 @@ A_FireBFG
 ( player_t*	player,
   pspdef_t*	psp )
 {
-    player->ammo[weaponinfo[player->readyweapon].ammo] -= deh_bfg_cells_per_shot;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo,
+                 deh_bfg_cells_per_shot);
     P_SpawnPlayerMissile (player->mo, MT_BFG);
 }

@@ -578,7 +596,7 @@ A_FirePlasma
 ( player_t*	player,
   pspdef_t*	psp )
 {
-    player->ammo[weaponinfo[player->readyweapon].ammo]--;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 1);

     P_SetPsprite (player,
 		  ps_flash,
@@ -650,7 +668,7 @@ A_FirePistol
     S_StartSound (player->mo, sfx_pistol);

     P_SetMobjState (player->mo, S_PLAY_ATK2);
-    player->ammo[weaponinfo[player->readyweapon].ammo]--;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 1);

     P_SetPsprite (player,
 		  ps_flash,
@@ -674,7 +692,7 @@ A_FireShotgun
     S_StartSound (player->mo, sfx_shotgn);
     P_SetMobjState (player->mo, S_PLAY_ATK2);

-    player->ammo[weaponinfo[player->readyweapon].ammo]--;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 1);

     P_SetPsprite (player,
 		  ps_flash,
@@ -704,7 +722,7 @@ A_FireShotgun2
     S_StartSound (player->mo, sfx_dshtgn);
     P_SetMobjState (player->mo, S_PLAY_ATK2);

-    player->ammo[weaponinfo[player->readyweapon].ammo]-=2;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 2);

     P_SetPsprite (player,
 		  ps_flash,
@@ -739,7 +757,7 @@ A_FireCGun
 	return;

     P_SetMobjState (player->mo, S_PLAY_ATK2);
-    player->ammo[weaponinfo[player->readyweapon].ammo]--;
+    DecreaseAmmo(player, weaponinfo[player->readyweapon].ammo, 1);

     P_SetPsprite (player,
 		  ps_flash,