From 617fac98d0df82c4beda446547ca021b7a12d9dd Mon Sep 17 00:00:00 2001
From: Michael Levin <risujin@fastmail.fm>
Date: Sat, 3 Oct 2009 11:26:03 +0000
Subject: * Build delay pie slices are now 5 sec each for both teams * Removed
 individual weapon build delay * Removed Advanced Construction Kit, everything
 is built by the normal kit * S2+ buildables cannot be built by regular
 grangers * Clicking to pick team during spectator mode fixed * New cvar:
 cg_printDuplicate, when set to 0 (default) prevents duplicate messages from
 being printed to screen (they still show up in console) * Pressing ESC while
 editing a UI item (esp. new Say menu) will not cause your cursor to disappear
 next time you open a menu

---
 src/cgame/cg_buildable.c |   1 -
 src/cgame/cg_draw.c      |  92 +++++++++++++-----------------------------
 src/cgame/cg_main.c      |  13 +++++-
 src/cgame/cg_tutorial.c  |   1 -
 src/game/bg_misc.c       | 103 +++++++----------------------------------------
 src/game/bg_public.h     |   3 --
 src/game/g_active.c      |  10 ++---
 src/game/g_client.c      |   1 +
 src/game/g_cmds.c        |  15 ++-----
 src/game/g_weapon.c      |  41 +++++++------------
 src/game/tremulous.h     |  10 ++---
 src/ui/ui_main.c         |   6 +--
 src/ui/ui_shared.c       |   8 ++--
 13 files changed, 86 insertions(+), 218 deletions(-)

diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
index 0a1f3877..054068f4 100644
--- a/src/cgame/cg_buildable.c
+++ b/src/cgame/cg_buildable.c
@@ -1184,7 +1184,6 @@ static qboolean CG_PlayerIsBuilder( buildable_t buildable )
     case WP_ABUILD:
     case WP_ABUILD2:
     case WP_HBUILD:
-    case WP_HBUILD2:
       return BG_FindTeamForBuildable( buildable ) ==
              BG_FindTeamForWeapon( cg.predictedPlayerState.weapon );
 
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 4720fd0f..08433c44 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -515,13 +515,9 @@ static void CG_DrawPlayerClipsRing( rectDef_t *rect, vec4_t color, qhandle_t sha
     case WP_ABUILD:
     case WP_ABUILD2:
     case WP_HBUILD:
-    case WP_HBUILD2:
-      maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon );
-
-      if( buildTime > maxDelay )
-        buildTime = maxDelay;
-
-      progress = ( maxDelay - buildTime ) / maxDelay;
+      if( buildTime > MAXIMUM_BUILD_TIME )
+        buildTime = MAXIMUM_BUILD_TIME;
+      progress = ( MAXIMUM_BUILD_TIME - buildTime ) / MAXIMUM_BUILD_TIME;
 
       color[ 3 ] = HH_MIN_ALPHA + ( progress * HH_ALPHA_DIFF );
       break;
@@ -553,16 +549,13 @@ static void CG_DrawPlayerBuildTimerRing( rectDef_t *rect, vec4_t color, qhandle_
   centity_t     *cent;
   float         buildTime = ps->stats[ STAT_MISC ];
   float         progress;
-  float         maxDelay;
 
   cent = &cg_entities[ cg.snap->ps.clientNum ];
 
-  maxDelay = (float)BG_FindBuildDelayForWeapon( cent->currentState.weapon );
+  if( buildTime > MAXIMUM_BUILD_TIME )
+    buildTime = MAXIMUM_BUILD_TIME;
 
-  if( buildTime > maxDelay )
-    buildTime = maxDelay;
-
-  progress = ( maxDelay - buildTime ) / maxDelay;
+  progress = ( MAXIMUM_BUILD_TIME - buildTime ) / MAXIMUM_BUILD_TIME;
 
   color[ 3 ] = AH_MIN_ALPHA + ( progress * AH_ALPHA_DIFF );
 
@@ -700,7 +693,6 @@ static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color )
         break;
 
       case WP_HBUILD:
-      case WP_HBUILD2:
         //percentage of BP remaining
         value = cgs.humanBuildPoints;
         break;
@@ -785,7 +777,6 @@ static void CG_DrawUsableBuildable( rectDef_t *rect, qhandle_t shader, vec4_t co
 
 static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
 {
-  float         progress;
   int           index;
   centity_t     *cent;
   playerState_t *ps;
@@ -793,56 +784,30 @@ static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
   cent = &cg_entities[ cg.snap->ps.clientNum ];
   ps = &cg.snap->ps;
 
-  if( cent->currentState.weapon )
-  {
-    switch( cent->currentState.weapon )
-    {
-      case WP_ABUILD:
-        progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_BASE_DELAY;
-        break;
-
-      case WP_ABUILD2:
-        progress = (float)ps->stats[ STAT_MISC ] / (float)ABUILDER_ADV_DELAY;
-        break;
-
-      case WP_HBUILD:
-        progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD_DELAY;
-        break;
-
-      case WP_HBUILD2:
-        progress = (float)ps->stats[ STAT_MISC ] / (float)HBUILD2_DELAY;
-        break;
-
-      default:
-        return;
-        break;
-    }
-
-    if( !ps->stats[ STAT_MISC ] )
-      return;
-
-    index = (int)( progress * 8.0f );
-
-    if( index > 7 )
-      index = 7;
-    else if( index < 0 )
-      index = 0;
+  if( ( cent->currentState.weapon != WP_ABUILD &&
+        cent->currentState.weapon != WP_ABUILD2 &&
+        cent->currentState.weapon != WP_HBUILD ) ||
+      ps->stats[ STAT_MISC ] <= 0 )
+    return;
 
-    if( cg.time - cg.lastBuildAttempt <= BUILD_DELAY_TIME )
-    {
-      if( ( ( cg.time - cg.lastBuildAttempt ) / 300 ) % 2 )
-      {
-        color[ 0 ] = 1.0f;
-        color[ 1 ] = color[ 2 ] = 0.0f;
-        color[ 3 ] = 1.0f;
-      }
-    }
+  index = 8 * ( ps->stats[ STAT_MISC ] - 1 ) / MAXIMUM_BUILD_TIME;
+  if( index > 7 )
+    index = 7;
+  else if( index < 0 )
+    index = 0;
 
-    trap_R_SetColor( color );
-    CG_DrawPic( rect->x, rect->y, rect->w, rect->h,
-      cgs.media.buildWeaponTimerPie[ index ] );
-    trap_R_SetColor( NULL );
+  if( cg.time - cg.lastBuildAttempt <= BUILD_DELAY_TIME &&
+      ( ( cg.time - cg.lastBuildAttempt ) / 300 ) % 2 )
+  {
+    color[ 0 ] = 1.0f;
+    color[ 1 ] = color[ 2 ] = 0.0f;
+    color[ 3 ] = 1.0f;
   }
+
+  trap_R_SetColor( color );
+  CG_DrawPic( rect->x, rect->y, rect->w, rect->h,
+              cgs.media.buildWeaponTimerPie[ index ] );
+  trap_R_SetColor( NULL );
 }
 
 static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color )
@@ -861,7 +826,6 @@ static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color )
       case WP_ABUILD:
       case WP_ABUILD2:
       case WP_HBUILD:
-      case WP_HBUILD2:
         break;
 
       default:
@@ -2005,9 +1969,7 @@ static void CG_DrawCrosshair( void )
 
   if( cg_drawCrosshair.integer == CROSSHAIR_RANGEDONLY &&
       !BG_FindLongRangedForWeapon( cg.snap->ps.weapon ) )
-  {
     return;
-  } 
 
   if( ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) ||
       ( cg.snap->ps.stats[ STAT_STATE ] & SS_INFESTING ) ||
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 8c472321..ac0715fe 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -176,6 +176,7 @@ vmCvar_t  cg_drawTeamOverlay;
 vmCvar_t  cg_teamOverlayUserinfo;
 vmCvar_t  cg_drawFriend;
 vmCvar_t  cg_teamChatsOnly;
+vmCvar_t  cg_printDuplicate;
 vmCvar_t  cg_noVoiceChats;
 vmCvar_t  cg_noVoiceText;
 vmCvar_t  cg_hudFiles;
@@ -313,6 +314,7 @@ static cvarTable_t cvarTable[ ] =
   { &cg_stats, "cg_stats", "0", 0 },
   { &cg_drawFriend, "cg_drawFriend", "1", CVAR_ARCHIVE },
   { &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
+  { &cg_printDuplicate, "cg_printDuplicate", "0", CVAR_ARCHIVE },
   { &cg_noVoiceChats, "cg_noVoiceChats", "0", CVAR_ARCHIVE },
   { &cg_noVoiceText, "cg_noVoiceText", "0", CVAR_ARCHIVE },
   { &cg_drawSurfNormal, "cg_drawSurfNormal", "0", CVAR_CHEAT },
@@ -547,6 +549,7 @@ CG_AddNotifyText
 void CG_AddNotifyText( void )
 {
   char buffer[ BIG_INFO_STRING ];
+  int bufferLen, textLen;
 
   trap_LiteralArgs( buffer, BIG_INFO_STRING );
 
@@ -557,12 +560,20 @@ void CG_AddNotifyText( void )
     return;
   }
 
+  bufferLen = strlen( buffer );
+  textLen = strlen( cg.consoleText );
+  
+  // Ignore console messages that were just printed
+  if( !cg_printDuplicate.integer && textLen >= bufferLen &&
+      !strcmp( cg.consoleText + textLen - bufferLen, buffer ) )
+    return;
+      
   if( cg.numConsoleLines == MAX_CONSOLE_LINES )
     CG_RemoveNotifyLine( );
 
   Q_strcat( cg.consoleText, MAX_CONSOLE_TEXT, buffer );
   cg.consoleLines[ cg.numConsoleLines ].time = cg.time;
-  cg.consoleLines[ cg.numConsoleLines ].length = strlen( buffer );
+  cg.consoleLines[ cg.numConsoleLines ].length = bufferLen;
   cg.numConsoleLines++;
 }
 
diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c
index 04d0ec28..9bd258fb 100644
--- a/src/cgame/cg_tutorial.c
+++ b/src/cgame/cg_tutorial.c
@@ -502,7 +502,6 @@ static void CG_HumanText( char *text, playerState_t *ps )
         break;
 
       case WP_HBUILD:
-      case WP_HBUILD2:
         CG_HumanCkitText( text, ps );
         break;
 
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 3c66bab8..5198fb28 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -138,7 +138,7 @@ buildableAttributes_t bg_buildableList[ ] =
     BOOSTER_SPLASHRADIUS,  //int       splashRadius;
     MOD_ASPAWN,            //int       meansOfDeath;
     BIT_ALIENS,            //int       team;
-    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_ABUILD2 ),   //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     BOOSTER_BT,            //int       buildTime;
@@ -217,7 +217,7 @@ buildableAttributes_t bg_buildableList[ ] =
     HIVE_SPLASHRADIUS,     //int       splashRadius;
     MOD_ASPAWN,            //int       meansOfDeath;
     BIT_ALIENS,            //int       team;
-    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_ABUILD2 ),   //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     500,                   //int       nextthink;
     HIVE_BT,               //int       buildTime;
@@ -257,7 +257,7 @@ buildableAttributes_t bg_buildableList[ ] =
     TRAPPER_SPLASHRADIUS,  //int       splashRadius;
     MOD_ASPAWN,            //int       meansOfDeath;
     BIT_ALIENS,            //int       team;
-    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_ABUILD2 ),   //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     TRAPPER_BT,            //int       buildTime;
@@ -337,7 +337,7 @@ buildableAttributes_t bg_buildableList[ ] =
     HOVEL_SPLASHRADIUS,    //int       splashRadius;
     MOD_ASPAWN,            //int       meansOfDeath;
     BIT_ALIENS,            //int       team;
-    ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_ABUILD2 ),   //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     150,                   //int       nextthink;
     HOVEL_BT,              //int       buildTime;
@@ -377,7 +377,7 @@ buildableAttributes_t bg_buildableList[ ] =
     HSPAWN_SPLASHRADIUS,   //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     HSPAWN_BT,             //int       buildTime;
@@ -418,7 +418,7 @@ buildableAttributes_t bg_buildableList[ ] =
     MEDISTAT_SPLASHRADIUS, //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     MEDISTAT_BT,           //int       buildTime;
@@ -460,7 +460,7 @@ buildableAttributes_t bg_buildableList[ ] =
     MGTURRET_SPLASHRADIUS, //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),   //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     50,                    //int       nextthink;
     MGTURRET_BT,           //int       buildTime;
@@ -500,7 +500,7 @@ buildableAttributes_t bg_buildableList[ ] =
     TESLAGEN_SPLASHRADIUS, //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     150,                   //int       nextthink;
     TESLAGEN_BT,           //int       buildTime;
@@ -540,7 +540,7 @@ buildableAttributes_t bg_buildableList[ ] =
     DC_SPLASHRADIUS,       //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD2 ),   //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     DC_BT,                 //int       buildTime;
@@ -580,7 +580,7 @@ buildableAttributes_t bg_buildableList[ ] =
     ARMOURY_SPLASHRADIUS,  //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     ARMOURY_BT,            //int       buildTime;
@@ -620,7 +620,7 @@ buildableAttributes_t bg_buildableList[ ] =
     REACTOR_SPLASHRADIUS,  //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     REACTOR_ATTACK_DCC_REPEAT, //int       nextthink;
     REACTOR_BT,            //int       buildTime;
@@ -660,7 +660,7 @@ buildableAttributes_t bg_buildableList[ ] =
     REPEATER_SPLASHRADIUS, //int       splashRadius;
     MOD_HSPAWN,            //int       meansOfDeath;
     BIT_HUMANS,            //int       team;
-    ( 1 << WP_HBUILD )|( 1 << WP_HBUILD2 ),    //weapon_t  buildWeapon;
+    ( 1 << WP_HBUILD ),    //weapon_t  buildWeapon;
     BANIM_IDLE1,           //int       idleAnim;
     100,                   //int       nextthink;
     REPEATER_BT,           //int       buildTime;
@@ -3244,7 +3244,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3271,7 +3270,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3299,7 +3297,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3327,7 +3324,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3355,7 +3351,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3384,7 +3379,6 @@ weaponAttributes_t bg_weapons[ ] =
     20.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3410,7 +3404,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3438,7 +3431,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3465,7 +3457,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3493,7 +3484,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3519,7 +3509,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3529,8 +3518,9 @@ weaponAttributes_t bg_weapons[ ] =
     SLOT_WEAPON,          //int       slots;
     "ckit",               //char      *weaponName;
     "Construction Kit",   //char      *weaponHumanName;
-    "Used for building basic structures. This includes "
-      "spawns, power and basic defense.",
+    "Used for building structures. This includes "
+      "spawns, power and basic defense. More structures become "
+      "available with new stages.",
     0,                    //int       maxAmmo;
     0,                    //int       maxClips;
     qtrue,                //int       infiniteAmmo;
@@ -3546,35 +3536,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    HBUILD_DELAY,         //int       buildDelay;
-    WUT_HUMANS            //WUTeam_t  team;
-  },
-  {
-    WP_HBUILD2,           //int       weaponNum;
-    HBUILD2_PRICE,        //int       price;
-    ( 1 << S2 )|( 1 << S3 ), //int  stages
-    SLOT_WEAPON,          //int       slots;
-    "ackit",              //char      *weaponName;
-    "Adv Construction Kit",//char      *weaponHumanName;
-    "Used for building basic and advanced structures. "
-      "Advanced structures include Defense Computers "
-      "and Tesla Generators.",
-    0,                    //int       maxAmmo;
-    0,                    //int       maxClips;
-    qtrue,                //int       infiniteAmmo;
-    qfalse,               //int       usesEnergy;
-    HBUILD2_REPEAT,       //int       repeatRate1;
-    HBUILD2_REPEAT,       //int       repeatRate2;
-    0,                    //int       repeatRate3;
-    0,                    //int       reloadTime;
-    0.0f,                 //float     knockbackScale;
-    qtrue,                //qboolean  hasAltMode;
-    qfalse,               //qboolean  hasThirdMode;
-    qfalse,               //qboolean  canZoom;
-    90.0f,                //float     zoomFov;
-    qtrue,                //qboolean  purchasable;
-    qfalse,               //qboolean  longRanged;
-    HBUILD2_DELAY,        //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3600,7 +3561,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    ABUILDER_BASE_DELAY,  //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3626,7 +3586,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qtrue,                //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    ABUILDER_ADV_DELAY,   //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3652,7 +3611,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3678,7 +3636,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3704,7 +3661,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3730,7 +3686,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3756,7 +3711,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3782,7 +3736,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3808,7 +3761,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qtrue,                //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3834,7 +3786,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3860,7 +3811,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3886,7 +3836,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_ALIENS            //WUTeam_t  team;
   },
   {
@@ -3912,7 +3861,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   },
   {
@@ -3938,7 +3886,6 @@ weaponAttributes_t bg_weapons[ ] =
     90.0f,                //float     zoomFov;
     qfalse,               //qboolean  purchasable;
     qfalse,               //qboolean  longRanged;
-    0,                    //int       buildDelay;
     WUT_HUMANS            //WUTeam_t  team;
   }
 };
@@ -4362,26 +4309,6 @@ qboolean BG_FindLongRangedForWeapon( int weapon )
   return qfalse;
 }
 
-/*
-==============
-BG_FindBuildDelayForWeapon
-==============
-*/
-int BG_FindBuildDelayForWeapon( int weapon )
-{
-  int i;
-
-  for( i = 0; i < bg_numWeapons; i++ )
-  {
-    if( bg_weapons[ i ].weaponNum == weapon )
-    {
-      return bg_weapons[ i ].buildDelay;
-    }
-  }
-
-  return 0;
-}
-
 /*
 ==============
 BG_FindTeamForWeapon
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 68af42cc..e3ffc434 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -354,7 +354,6 @@ typedef enum
   //build weapons must remain in a block
   WP_ABUILD,
   WP_ABUILD2,
-  WP_HBUILD2,
   WP_HBUILD,
   //ok?
 
@@ -1087,8 +1086,6 @@ typedef struct
   qboolean  purchasable;
   qboolean  longRanged;
 
-  int       buildDelay;
-
   WUTeam_t  team;
 } weaponAttributes_t;
 
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 9fe75f92..998040d9 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -418,11 +418,12 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )
   }
   
   // Check to see if we are in the spawn queue
-  queued = qfalse;
   if( client->pers.teamSelection == PTE_ALIENS )
     queued = G_SearchSpawnQueue( &level.alienSpawnQueue, ent - g_entities );
   else if( client->pers.teamSelection == PTE_HUMANS )
     queued = G_SearchSpawnQueue( &level.humanSpawnQueue, ent - g_entities );
+  else
+    queued = qfalse;
 
   // Wants to get out of spawn queue
   if( attack1 && queued )
@@ -438,8 +439,7 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )
     client->ps.pm_flags &= ~PMF_QUEUED;
     queued = qfalse;
   }
-  else if( attack1 && client->pers.teamSelection != PTE_NONE &&
-           client->pers.classSelection == PCL_NONE )
+  else if( attack1 )
   {
     // Wants to get into spawn queue
     if( client->sess.spectatorState == SPECTATOR_FOLLOW )
@@ -692,8 +692,7 @@ void ClientTimerActions( gentity_t *ent, int msec )
     }
 
     if( client->ps.weapon == WP_ABUILD || client->ps.weapon == WP_ABUILD2 ||
-      BG_InventoryContainsWeapon( WP_HBUILD, client->ps.stats ) ||
-      BG_InventoryContainsWeapon( WP_HBUILD2, client->ps.stats ) )
+        BG_InventoryContainsWeapon( WP_HBUILD, client->ps.stats ) )
     {
         //update build timer
         if( client->ps.stats[ STAT_MISC ] > 0 )
@@ -708,7 +707,6 @@ void ClientTimerActions( gentity_t *ent, int msec )
       case WP_ABUILD:
       case WP_ABUILD2:
       case WP_HBUILD:
-      case WP_HBUILD2:
         //set validity bit on buildable
         if( ( client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE )
         {
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 1a2714cb..9298eb55 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1462,6 +1462,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
   client->ps.stats[ STAT_WEAPONS ] = 0;
   client->ps.stats[ STAT_WEAPONS2 ] = 0;
   client->ps.stats[ STAT_SLOTS ] = 0;
+  client->ps.stats[ STAT_MISC ] = 0;
 
   client->ps.eFlags = flags;
   client->ps.clientNum = index;
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 2918e0be..88d11646 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -705,8 +705,7 @@ void Cmd_Team_f( gentity_t *ent )
   if( oldteam != PTE_NONE && ent->client->sess.sessionTeam != TEAM_SPECTATOR &&
      ( ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 ||
        ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG ||
-       BG_InventoryContainsWeapon( WP_HBUILD, ent->client->ps.stats ) ||
-       BG_InventoryContainsWeapon( WP_HBUILD2, ent->client->ps.stats ) ) &&
+       BG_InventoryContainsWeapon( WP_HBUILD, ent->client->ps.stats ) ) &&
       ent->client->ps.stats[ STAT_MISC ] > 0 )
   {
     if( ent->client->pers.teamSelection == PTE_ALIENS )
@@ -1577,12 +1576,6 @@ void Cmd_Class_f( gentity_t *ent )
       {
         ent->client->pers.humanItemSelection = WP_HBUILD;
       }
-      else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) &&
-               BG_WeaponIsAllowed( WP_HBUILD2 ) &&
-               BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) )
-      {
-        ent->client->pers.humanItemSelection = WP_HBUILD2;
-      }
       else
       {
         G_TriggerMenu( ent->client->ps.clientNum, MN_H_UNKNOWNSPAWNITEM );
@@ -2182,8 +2175,7 @@ void Cmd_Sell_f( gentity_t *ent )
     if( BG_InventoryContainsWeapon( weapon, ent->client->ps.stats ) )
     {
       //guard against selling the HBUILD weapons exploit
-      if( ( weapon == WP_HBUILD || weapon == WP_HBUILD2 ) &&
-          ent->client->ps.stats[ STAT_MISC ] > 0 )
+      if( weapon == WP_HBUILD && ent->client->ps.stats[ STAT_MISC ] > 0 )
       {
         G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER );
         return;
@@ -2240,8 +2232,7 @@ void Cmd_Sell_f( gentity_t *ent )
     for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
     {
       //guard against selling the HBUILD weapons exploit
-      if( ( i == WP_HBUILD || i == WP_HBUILD2 ) &&
-          ent->client->ps.stats[ STAT_MISC ] > 0 )
+      if( i == WP_HBUILD && ent->client->ps.stats[ STAT_MISC ] > 0 )
       {
         G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER );
         continue;
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 438350cf..fc915d86 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -863,27 +863,25 @@ void cancelBuildFire( gentity_t *ent )
   gentity_t   *traceEnt;
   int         bHealth;
 
+  // Cancel ghost buildable
   if( ent->client->ps.stats[ STAT_BUILDABLE ] != BA_NONE )
   {
     ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
     return;
   }
 
-  //repair buildable
+  // Construction kit repair
   if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
   {
     AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
     VectorMA( ent->client->ps.origin, 100, forward, end );
-
-    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID );
+    
+    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number,
+                MASK_PLAYERSOLID );
     traceEnt = &g_entities[ tr.entityNum ];
 
-    if( tr.fraction < 1.0 &&
-        ( traceEnt->s.eType == ET_BUILDABLE ) &&
-        ( traceEnt->biteam == ent->client->ps.stats[ STAT_PTEAM ] ) &&
-        ( ( ent->client->ps.weapon >= WP_HBUILD2 ) &&
-          ( ent->client->ps.weapon <= WP_HBUILD ) ) &&
-        traceEnt->spawned && traceEnt->health > 0 )
+    if( tr.fraction < 1.0f && traceEnt->spawned && traceEnt->health > 0 &&
+        traceEnt->s.eType == ET_BUILDABLE && traceEnt->biteam == BIT_HUMANS )
     {
       if( ent->client->ps.stats[ STAT_MISC ] > 0 )
       {
@@ -892,20 +890,20 @@ void cancelBuildFire( gentity_t *ent )
       }
 
       bHealth = BG_FindHealthForBuildable( traceEnt->s.modelindex );
-
       traceEnt->health += HBUILD_HEALRATE;
-
-      if( traceEnt->health > bHealth )
+      if( traceEnt->health >= bHealth )
+      {
         traceEnt->health = bHealth;
-
-      if( traceEnt->health == bHealth )
         G_AddEvent( ent, EV_BUILD_REPAIRED, 0 );
+      }
       else
         G_AddEvent( ent, EV_BUILD_REPAIR, 0 );
     }
   }
+  
+  // Granger slash
   else if( ent->client->ps.weapon == WP_ABUILD ||
-		  ent->client->ps.weapon == WP_ABUILD2 )
+           ent->client->ps.weapon == WP_ABUILD2 )
     meleeAttack( ent, ABUILDER_CLAW_RANGE, ABUILDER_CLAW_WIDTH,
                  ABUILDER_CLAW_WIDTH, ABUILDER_CLAW_DMG, MOD_ABUILDER_CLAW );
 }
@@ -930,22 +928,15 @@ void buildFire( gentity_t *ent, dynMenu_t menu )
 
     if( G_BuildIfValid( ent, buildable ) )
     {
-      if( g_cheats.integer )
-      {
-        ent->client->ps.stats[ STAT_MISC ] = 0;
-      }
-      else
+      if( !g_cheats.integer )
       {
         ent->client->ps.stats[ STAT_MISC ] +=
           BG_FindBuildTimeForBuildable( buildable );
       }
 
       ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
-
-      // don't want it bigger than 32k
-      if( ent->client->ps.stats[ STAT_MISC ] > 30000 )
-        ent->client->ps.stats[ STAT_MISC ] = 30000;
     }
+
     return;
   }
 
@@ -1525,7 +1516,6 @@ void FireWeapon2( gentity_t *ent )
     case WP_ABUILD:
     case WP_ABUILD2:
     case WP_HBUILD:
-    case WP_HBUILD2:
       cancelBuildFire( ent );
       break;
     default:
@@ -1633,7 +1623,6 @@ void FireWeapon( gentity_t *ent )
       buildFire( ent, MN_A_BUILD );
       break;
     case WP_HBUILD:
-    case WP_HBUILD2:
       buildFire( ent, MN_H_BUILD );
       break;
     default:
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 1262e836..0bcd81fe 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -41,8 +41,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #define ABUILDER_CLAW_WIDTH         4.0f
 #define ABUILDER_CLAW_REPEAT        1000
 #define ABUILDER_CLAW_K_SCALE       1.0f
-#define ABUILDER_BASE_DELAY         17000
-#define ABUILDER_ADV_DELAY          12000
 #define ABUILDER_BLOB_DMG           ADM(4)
 #define ABUILDER_BLOB_REPEAT        1000
 #define ABUILDER_BLOB_SPEED         800.0f
@@ -477,13 +475,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #define HBUILD_PRICE                0
 #define HBUILD_REPEAT               1000
-#define HBUILD_DELAY                17500
 #define HBUILD_HEALRATE             18
 
-#define HBUILD2_PRICE               0
-#define HBUILD2_REPEAT              1000
-#define HBUILD2_DELAY               15000
-
 /*
  * HUMAN upgrades
  */
@@ -675,3 +668,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #define DAMAGE_FRACTION_FOR_KILL    0.5f //how much damage players (versus structures) need to
                                          //do to increment the stage kill counters
+                                         
+#define MAXIMUM_BUILD_TIME          20000 // used for pie timer
+
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index 3a7e6d7e..fcc3799d 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -2224,11 +2224,7 @@ static void UI_LoadHumanItems( void )
 
   if( BG_WeaponIsAllowed( WP_MACHINEGUN ) )
     UI_AddItem( WP_MACHINEGUN );
-
-  if( BG_WeaponIsAllowed( WP_HBUILD2 ) &&
-      BG_FindStagesForWeapon( WP_HBUILD2, UI_GetCurrentHumanStage( ) ) )
-    UI_AddItem( WP_HBUILD2 );
-  else if( BG_WeaponIsAllowed( WP_HBUILD ) )
+  if( BG_WeaponIsAllowed( WP_HBUILD ) )
     UI_AddItem( WP_HBUILD );
 }
 
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index f0dce0bc..2b06329a 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -1566,7 +1566,12 @@ void Menus_CloseAll( qboolean force )
   }
 
   if( force )
+  {
     openMenuCount = 0;
+    g_editingField = qfalse;
+    g_waitingForKey = qfalse;
+    g_editItem = NULL;
+  }
 }
 
 
@@ -4075,9 +4080,6 @@ void Menu_HandleKey( menuDef_t *menu, int key, qboolean down )
   itemDef_t *item = NULL;
   qboolean inHandler = qfalse;
 
-  if( inHandler )
-    return;
-
   inHandler = qtrue;
 
   if( g_waitingForKey && down )
-- 
cgit