From 35ee9b1554981454b1a402e3764044299c9d0661 Mon Sep 17 00:00:00 2001
From: Tim Angus <tim@ngus.net>
Date: Sun, 17 Jul 2005 22:21:09 +0000
Subject: * Plugged the "sell and buy gets you full ammo" exploit * Changed
 voting system to need a majority of connected clients to pass without time
 out and a majority of voting clients to pass with time out

---
 src/game/g_cmds.c   | 108 +++++++++++++++++++++++++++++++---------------------
 src/game/g_local.h  |   1 +
 src/game/g_main.c   |  16 ++++++--
 src/game/g_weapon.c |   1 +
 4 files changed, 79 insertions(+), 47 deletions(-)

diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 6d0ba6da..03dcb33e 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -1441,6 +1441,58 @@ void Cmd_ToggleItem_f( gentity_t *ent )
     trap_SendServerCommand( ent-g_entities, va( "print \"You don't have the %s\n\"", s ) );
 }
 
+/*
+=================
+G_GiveClientMaxAmmo
+=================
+*/
+static void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
+{
+  int i;
+  int quan, clips, maxClips;
+
+  if( !ent->client->campingAtTheArmoury || !ent->client->firedWeapon )
+  {
+    qboolean weaponType;
+
+    for( i = WP_NONE; i < WP_NUM_WEAPONS; i++ )
+    {
+      if( buyingEnergyAmmo )
+        weaponType = BG_FindUsesEnergyForWeapon( i );
+      else
+        weaponType = !BG_FindUsesEnergyForWeapon( i );
+      
+      if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) &&
+          weaponType &&
+          !BG_FindInfinteAmmoForWeapon( i ) )
+      {
+        BG_FindAmmoForWeapon( i, &quan, &clips, &maxClips );
+        
+        if( buyingEnergyAmmo )
+        {
+          G_AddEvent( ent, EV_RPTUSE_SOUND, 0 );
+          ent->client->lastRefilTime = level.time;
+          
+          if( BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
+            quan = (int)( (float)quan * BATTPACK_MODIFIER );
+        }
+
+        BG_PackAmmoArray( i, ent->client->ps.ammo, ent->client->ps.powerups,
+                          quan, clips, maxClips );
+      }
+    }
+
+    ent->client->lastBoughtAmmoTime = level.time;
+    ent->client->campingAtTheArmoury = qtrue;
+  }
+  else
+  {
+    trap_SendServerCommand( ent-g_entities,
+        va( "print \"Move away or wait 45 seconds for ammo/energy\n\"" ) );
+    return;
+  }
+}
+
 /*
 =================
 Cmd_Buy_f
@@ -1551,8 +1603,14 @@ void Cmd_Buy_f( gentity_t *ent )
         BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
       quan = (int)( (float)quan * BATTPACK_MODIFIER );
     
-    BG_PackAmmoArray( weapon, ent->client->ps.ammo, ent->client->ps.powerups,
-                      quan, clips, maxClips );
+    if( ent->client->firedWeapon && ent->client->campingAtTheArmoury )
+      BG_PackAmmoArray( weapon, ent->client->ps.ammo, ent->client->ps.powerups,
+                        0, 0, maxClips );
+    else
+      BG_PackAmmoArray( weapon, ent->client->ps.ammo, ent->client->ps.powerups,
+                        quan, clips, maxClips );
+
+    ent->client->firedWeapon = qfalse;
 
     //force a weapon change
     ent->client->ps.pm_flags |= PMF_WEAPON_SWITCH;
@@ -1612,54 +1670,16 @@ void Cmd_Buy_f( gentity_t *ent )
     }
     
     if( upgrade == UP_AMMO )
-    {
-      if( !ent->client->campingAtTheArmoury )
-      {
-        qboolean weaponType;
-
-        for( i = WP_NONE; i < WP_NUM_WEAPONS; i++ )
-        {
-          if( buyingEnergyAmmo )
-            weaponType = BG_FindUsesEnergyForWeapon( i );
-          else
-            weaponType = !BG_FindUsesEnergyForWeapon( i );
-          
-          if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) &&
-              weaponType &&
-              !BG_FindInfinteAmmoForWeapon( i ) )
-          {
-            BG_FindAmmoForWeapon( i, &quan, &clips, &maxClips );
-            
-            if( buyingEnergyAmmo )
-            {
-              G_AddEvent( ent, EV_RPTUSE_SOUND, 0 );
-              ent->client->lastRefilTime = level.time;
-              
-              if( BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
-                quan = (int)( (float)quan * BATTPACK_MODIFIER );
-            }
-
-            BG_PackAmmoArray( i, ent->client->ps.ammo, ent->client->ps.powerups,
-                              quan, clips, maxClips );
-          }
-        }
-
-        ent->client->lastBoughtAmmoTime = level.time;
-        ent->client->campingAtTheArmoury = qtrue;
-      }
-      else
-      {
-        trap_SendServerCommand( ent-g_entities,
-            va( "print \"Move away or wait 45 seconds for ammo/energy\n\"" ) );
-        return;
-      }
-    }
+      G_GiveClientMaxAmmo( ent, buyingEnergyAmmo );
     else
     {
       //add to inventory
       BG_AddUpgradeToInventory( upgrade, ent->client->ps.stats );
     }
     
+    if( upgrade == UP_BATTPACK )
+      G_GiveClientMaxAmmo( ent, qtrue );
+
     //subtract from funds
     G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse );
   }
diff --git a/src/game/g_local.h b/src/game/g_local.h
index c0f4db88..8ab0a200 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -420,6 +420,7 @@ struct gclient_s
 
   int                 lastBoughtAmmoTime;
   qboolean            campingAtTheArmoury;
+  qboolean            firedWeapon;
 };
 
 
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 15b19df9..94175c4d 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -1649,17 +1649,27 @@ void CheckVote( void )
   
   if( level.time - level.voteTime >= VOTE_TIME )
   {
-    trap_SendServerCommand( -1, "print \"Vote failed.\n\"" );
+    if( level.voteYes > level.voteNo )
+    {
+      // execute the command, then remove the vote
+      trap_SendServerCommand( -1, "print \"Vote passed.\n\"" );
+      level.voteExecuteTime = level.time + 3000;
+    }
+    else
+    {
+      // same behavior as a timeout
+      trap_SendServerCommand( -1, "print \"Vote failed.\n\"" );
+    }
   }
   else
   {
-    if( level.voteYes > level.numVotingClients / 2 )
+    if( level.voteYes > level.numConnectedClients / 2 )
     {
       // execute the command, then remove the vote
       trap_SendServerCommand( -1, "print \"Vote passed.\n\"" );
       level.voteExecuteTime = level.time + 3000;
     }
-    else if( level.voteNo >= level.numVotingClients / 2 )
+    else if( level.voteNo >= level.numConnectedClients / 2 )
     {
       // same behavior as a timeout
       trap_SendServerCommand( -1, "print \"Vote failed.\n\"" );
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 5c26002a..2e94ed7e 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -1181,6 +1181,7 @@ void FireWeapon( gentity_t *ent )
     // set aiming directions
     AngleVectors( ent->client->ps.viewangles, forward, right, up );
     CalcMuzzlePoint( ent, forward, right, up, muzzle );
+    ent->client->firedWeapon = qtrue;
   }
   else
   {
-- 
cgit