From beb34e28a4f933107a3fa08a306125a712e885ad Mon Sep 17 00:00:00 2001
From: Tim Angus <tim@ngus.net>
Date: Sat, 5 Jul 2003 03:04:29 +0000
Subject: * Hopefully eliminated all the BG_Find... fallthroughs for the
 classes * Introduced a really hacky fix to a model caching bug
 (ClientInfoChanged)

---
 src/cgame/cg_event.c |  8 +++---
 src/cgame/cg_view.c  | 70 +++++++++++++++++++++++++++++-----------------------
 src/game/bg_misc.c   | 34 ++++++++++++++++++++-----
 src/game/g_client.c  | 39 +++++++++++++++++++++--------
 src/game/g_cmds.c    | 14 ++++-------
 5 files changed, 105 insertions(+), 60 deletions(-)

(limited to 'src')

diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index 857de9d8..017750c7 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -311,7 +311,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
   clientInfo_t  *ci;
   int           steptime, i;
 
-  steptime = BG_FindSteptimeForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
+  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
+    steptime = 200;
+  else
+    steptime = BG_FindSteptimeForClass( cg.snap->ps.stats[ STAT_PCLASS ] );
 
   es = &cent->currentState;
   event = es->event & ~EV_EVENT_BITS;
@@ -442,8 +445,6 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
         float	oldStep;
         int		delta;
         int		step;
-        float steptime;
-        playerState_t *ps = &cg.predictedPlayerState;
 
         if( clientNum != cg.predictedPlayerState.clientNum )
           break;
@@ -455,7 +456,6 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
         
         // check for stepping up before a previous step is completed
         delta = cg.time - cg.stepTime;
-        steptime = BG_FindSteptimeForClass( ps->stats[ STAT_PCLASS ] );
         
         if( delta < steptime )
           oldStep = cg.stepChange * ( steptime - delta ) / steptime;
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index ac180304..f69984bd 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -337,7 +337,10 @@ static void CG_StepOffset( void )
   else
     VectorSet( normal, 0.0f, 0.0f, 1.0f );
  
-  steptime = BG_FindSteptimeForClass( ps->stats[ STAT_PCLASS ] );
+  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
+    steptime = 200;
+  else
+    steptime = BG_FindSteptimeForClass( ps->stats[ STAT_PCLASS ] );
   
 	// smooth out stair climbing
 	timeDelta = cg.time - cg.stepTime;
@@ -453,8 +456,13 @@ static void CG_OffsetFirstPersonView( void )
 
   // add angles based on bob
   //TA: bob amount is class dependant
-  bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
-  if( bob2 != 0 )
+  
+  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
+    bob2 = 0.0f;
+  else
+    bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
+  
+  if( bob2 != 0.0f )
   {
     // make sure the bob is visible even at low speeds
     speed = cg.xyspeed > 200 ? cg.xyspeed : 200;
@@ -788,9 +796,8 @@ static int CG_CalcFov( void )
   int   a;
   float b;
 
-  attribFov = BG_FindFovForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
-
-  if( cg.predictedPlayerState.pm_type == PM_INTERMISSION )
+  if( cg.predictedPlayerState.pm_type == PM_INTERMISSION ||
+      ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) )
   {
     // if in intermission, use a fixed value
     fov_x = 90;
@@ -798,6 +805,7 @@ static int CG_CalcFov( void )
   else
   {
     //TA: don't lock the fov globally - we need to be able to change it
+    attribFov = BG_FindFovForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
     fov_x = attribFov;
 
     if ( fov_x < 1 )
@@ -817,35 +825,35 @@ static int CG_CalcFov( void )
 
       fov_x = 180 - temp2;
     }
-  }
-
-  // account for zooms
-  zoomFov = cg_zoomFov.value;
-  if ( zoomFov < 1 )
-    zoomFov = 1;
-  else if ( zoomFov > attribFov )
-    zoomFov = attribFov;
-
-  //TA: only do all the zoom stuff if the client CAN zoom
-  if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_CANZOOM ) )
-  {
-    if ( cg.zoomed )
+  
+    // account for zooms
+    zoomFov = cg_zoomFov.value;
+    if ( zoomFov < 1 )
+      zoomFov = 1;
+    else if ( zoomFov > attribFov )
+      zoomFov = attribFov;
+
+    //TA: only do all the zoom stuff if the client CAN zoom
+    if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_CANZOOM ) )
     {
-      f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
+      if ( cg.zoomed )
+      {
+        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
 
-      if ( f > 1.0 )
-        fov_x = zoomFov;
+        if ( f > 1.0 )
+          fov_x = zoomFov;
+        else
+          fov_x = fov_x + f * ( zoomFov - fov_x );
+      }
       else
-        fov_x = fov_x + f * ( zoomFov - fov_x );
-    }
-    else
-    {
-      f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
+      {
+        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
 
-      if ( f > 1.0 )
-        fov_x = fov_x;
-      else
-        fov_x = zoomFov + f * ( fov_x - zoomFov );
+        if ( f > 1.0 )
+          fov_x = fov_x;
+        else
+          fov_x = zoomFov + f * ( fov_x - zoomFov );
+      }
     }
   }
 
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 17d47de5..1b2f9777 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -1186,7 +1186,7 @@ classAttributes_t bg_classList[ ] =
     PCL_A_B_BASE,                                   //int     classnum;
     "builder",                                      //char    *className;
     "Builder",                                      //char    *humanName;
-    "lucy",                                         //char    *modelname;
+    "builder",                                      //char    *modelname;
     1.0f,                                           //float   modelScale;
     "default",                                      //char    *skinname;
     "alien_builder_hud",                            //char    *hudname;
@@ -1216,9 +1216,9 @@ classAttributes_t bg_classList[ ] =
     PCL_A_B_LEV1,                                   //int     classnum;
     "builderupg",                                   //char    *classname;
     "Advanced Builder",                             //char    *humanname;
-    "lucy",                                         //char    *modelname;
+    "builder",                                      //char    *modelname;
     1.0f,                                           //float   modelScale;
-    "angel",                                        //char    *skinname;
+    "advanced",                                     //char    *skinname;
     "alien_builder_hud",                            //char    *hudname;
     ( 1 << S2 )|( 1 << S3 ),                        //int  stages
     { -20, -20, -20 },                              //vec3_t  mins;
@@ -1564,6 +1564,7 @@ char *BG_FindNameForClassNum( int pclass )
       return bg_classList[ i ].className;
   }
 
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindNameForClassNum\n" );
   //wimp out
   return 0;
 }
@@ -1583,6 +1584,7 @@ char *BG_FindHumanNameForClassNum( int pclass )
       return bg_classList[ i ].humanName;
   }
 
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHumanNameForClassNum\n" );
   //wimp out
   return 0;
 }
@@ -1602,6 +1604,7 @@ char *BG_FindModelNameForClass( int pclass )
       return bg_classList[ i ].modelName;
   }
 
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelNameForClass\n" );
   //note: must return a valid modelName!
   return bg_classList[ 0 ].modelName;
 }
@@ -1623,6 +1626,7 @@ float BG_FindModelScaleForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindModelScaleForClass\n" );
   return 1.0f;
 }
 
@@ -1641,6 +1645,7 @@ char *BG_FindSkinNameForClass( int pclass )
       return bg_classList[ i ].skinName;
   }
 
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSkinNameForClass\n" );
   //note: must return a valid modelName!
   return bg_classList[ 0 ].skinName;
 }
@@ -1660,6 +1665,7 @@ char *BG_FindHudNameForClass( int pclass )
       return bg_classList[ i ].hudName;
   }
 
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHudNameForClass\n" );
   //note: must return a valid hudName!
   return bg_classList[ 0 ].hudName;
 }
@@ -1684,6 +1690,7 @@ qboolean BG_FindStagesForClass( int pclass, stage_t stage )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStagesForClass\n" );
   return qfalse;
 }
 
@@ -1782,6 +1789,7 @@ int BG_FindHealthForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindHealthForClass\n" );
   return 100;
 }
 
@@ -1802,6 +1810,7 @@ int BG_FindRegenRateForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindRegenRateForClass\n" );
   return 0;
 }
 
@@ -1822,6 +1831,7 @@ int BG_FindFovForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFovForClass\n" );
   return 90;
 }
 
@@ -1842,6 +1852,7 @@ float BG_FindBobForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBobForClass\n" );
   return 0.002;
 }
 
@@ -1862,7 +1873,8 @@ float BG_FindSpeedForClass( int pclass )
     }
   }
   
-  return 1.0;
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSpeedForClass\n" );
+  return 1.0f;
 }
 
 /*
@@ -1882,7 +1894,8 @@ float BG_FindStickyForClass( int pclass )
     }
   }
   
-  return 1.0;
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStickyForClass\n" );
+  return 1.0f;
 }
 
 /*
@@ -1902,6 +1915,7 @@ int BG_FindSteptimeForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindSteptimeForClass\n" );
   return 200;
 }
 
@@ -1946,6 +1960,7 @@ weapon_t BG_FindStartWeaponForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStartWeaponForClass\n" );
   return WP_NONE;
 }
 
@@ -1966,6 +1981,7 @@ float BG_FindBuildDistForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindBuildDistForClass\n" );
   return 0.0f;
 }
 
@@ -2025,6 +2041,7 @@ int BG_FindEvolveTimeForClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindEvolveTimeForClass\n" );
   return 5000;
 }
 
@@ -2045,6 +2062,7 @@ int BG_FindValueOfClass( int pclass )
     }
   }
   
+  Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindValueOfClass\n" );
   return 0;
 }
 
@@ -3529,7 +3547,9 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean
 
   if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR || ps->pm_type == PM_FREEZE )
     s->eType = ET_INVISIBLE;
-  else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH )
+  else if( ps->stats[STAT_HEALTH] <= GIB_HEALTH )
+    s->eType = ET_INVISIBLE;
+  else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
     s->eType = ET_INVISIBLE;
   else
     s->eType = ET_PLAYER;
@@ -3629,6 +3649,8 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s
     s->eType = ET_INVISIBLE;
   else if( ps->stats[STAT_HEALTH] <= GIB_HEALTH )
     s->eType = ET_INVISIBLE;
+  else if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
+    s->eType = ET_INVISIBLE;
   else
     s->eType = ET_PLAYER;
 
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 4c95708a..8e3fdaf1 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1041,6 +1041,15 @@ void ClientUserinfoChanged( int clientNum )
     Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_H_BSUIT ),
                                               BG_FindSkinNameForClass( PCL_H_BSUIT ) );
   }
+  else if( client->pers.pclass == PCL_NONE )
+  {
+    //This looks hacky and frankly it is. The clientInfo string needs to hold different
+    //model details to that of the spawning class or the info change will not be
+    //registered and an axis appears instead of the player model. There is zero chance
+    //the player can spawn with the battlesuit, hence this choice.
+    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_H_BSUIT ),
+                                              BG_FindSkinNameForClass( PCL_H_BSUIT ) );
+  }
   else
   {
     Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( client->pers.pclass ),
@@ -1048,13 +1057,18 @@ void ClientUserinfoChanged( int clientNum )
   }
   Q_strncpyz( model, buffer, sizeof( model ) );
 
-  //model segmentation
-  Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg",
-               BG_FindModelNameForClass( client->pers.pclass ) );
-  if( G_NonSegModel( filename ) )
-    client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL;
-  else
-    client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL;
+  //don't bother setting model type if spectating
+  if( client->pers.pclass != PCL_NONE )
+  {
+    //model segmentation
+    Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg",
+                 BG_FindModelNameForClass( client->pers.pclass ) );
+
+    if( G_NonSegModel( filename ) )
+      client->ps.persistant[ PERS_STATE ] |= PS_NONSEGMODEL;
+    else
+      client->ps.persistant[ PERS_STATE ] &= ~PS_NONSEGMODEL;
+  }
 
   // wallwalk follow
   s = Info_ValueForKey( userinfo, "cg_wwFollow" );
@@ -1402,14 +1416,19 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn )
       hModifier = ALIENSTAGE3_HLTH_MODIFIER;
   }
   
-  client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] =
-    (int)( (float)BG_FindHealthForClass( ent->client->pers.pclass ) * hModifier );
+  if( client->sess.sessionTeam != TEAM_SPECTATOR )
+    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] =
+      (int)( (float)BG_FindHealthForClass( ent->client->pers.pclass ) * hModifier );
+  else
+    client->pers.maxHealth = client->ps.stats[ STAT_MAX_HEALTH ] = 100;
 
   // clear entity values
   if( ent->client->pers.pclass == PCL_H_BASE )
     weapon = client->pers.pitem;
-  else
+  else if( client->sess.sessionTeam != TEAM_SPECTATOR )
     weapon = BG_FindStartWeaponForClass( ent->client->pers.pclass );
+  else
+    weapon = WP_NONE;
   
   BG_FindAmmoForWeapon( weapon, &ammo, &clips, &maxClips );
   BG_packWeapon( weapon, client->ps.stats );
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index a95f45ea..888743f2 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -1824,15 +1824,11 @@ void Cmd_Test_f( gentity_t *ent )
   if( !CheatsOk( ent ) )
     return;
 
-/*  ent->client->ps.stats[ STAT_STATE ] |= SS_KNOCKEDOVER;
-  ent->client->lastKnockedOverTime = level.time;
-  G_AddPredictableEvent( ent, EV_KNOCKOVER, 0 );
-  VectorCopy( ent->client->ps.viewangles, ent->client->ps.grapplePoint );
-  
-  ent->client->ps.legsAnim =
-    ( ( ent->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | BOTH_DEATH1;
-  ent->client->ps.torsoAnim =
-    ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | BOTH_DEATH1;*/
+  G_Printf( "%d %d %d\n",
+      ent->client->sess.sessionTeam,
+      ent->client->ps.stats[ STAT_PTEAM ],
+      ent->client->ps.persistant[ PERS_TEAM ]
+      );
 }
 
 /*
-- 
cgit