codemp/cgame/cg_players.c File Reference

#include "cg_local.h"
#include "..\ghoul2\g2.h"
#include "bg_saga.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Defines

#define TURN_ON   0x00000000
#define TURN_OFF   0x00000100
#define MAX_SURF_LIST_SIZE   1024
#define DEFAULT_FEMALE_SOUNDPATH   "chars/mp_generic_female/misc"
#define DEFAULT_MALE_SOUNDPATH   "chars/mp_generic_male/misc"
#define FOOTSTEP_DISTANCE   32
#define SHADOW_DISTANCE   128
#define REFRACT_EFFECT_DURATION   500
#define MAX_SHIELD_TIME   2000.0
#define MIN_SHIELD_TIME   2000.0
#define MAX_MARK_FRAGMENTS   128
#define MAX_MARK_POINTS   384
#define CG_MAX_SABER_COMP_TIME   400
#define SABER_TRAIL_TIME   40.0f
#define FX_USE_ALPHA   0x08000000
#define SPEED_TRAIL_DISTANCE   6
#define SMOOTH_G2ANIM_LERPANGLES
#define JETPACK_MODEL   "models/weapons2/jetpack/model.glm"
#define RARMBIT   (1 << (G2_MODELPART_RARM-10))
#define RHANDBIT   (1 << (G2_MODELPART_RHAND-10))
#define WAISTBIT   (1 << (G2_MODELPART_WAIST-10))
#define FLYBYSOUNDTIME   2000

Functions

void CG_AddRadarEnt (centity_t *cent)
void CG_AddBracketedEnt (centity_t *cent)
qboolean CG_InFighter (void)
qboolean WP_SaberBladeUseSecondBladeStyle (saberInfo_t *saber, int bladeNum)
void CG_Disintegration (centity_t *cent, refEntity_t *ent)
sfxHandle_t CG_CustomSound (int clientNum, const char *soundName)
qboolean CG_ParseSurfsFile (const char *modelName, const char *skinName, char *surfOff, char *surfOn)
qboolean BG_IsValidCharacterModel (const char *modelName, const char *skinName)
qboolean BG_ValidateSkinForTeam (const char *modelName, char *skinName, int team, float *colors)
int CG_G2SkelForModel (void *g2)
int CG_G2EvIndexForModel (void *g2, int animIndex)
void CG_LoadCISounds (clientInfo_t *ci, qboolean modelloaded)
void CG_LoadClientInfo (clientInfo_t *ci)
void WP_SetSaber (int entNum, saberInfo_t *sabers, int saberNum, const char *saberName)
void CG_NewClientInfo (int clientNum, qboolean entitiesInitialized)
void CG_ActualLoadDeferredPlayers (void)
void CG_LoadDeferredPlayers (void)
void CG_PlayerAnimEventDo (centity_t *cent, animevent_t *animEvent)
void CG_PlayerAnimEvents (int animFileIndex, int eventFileIndex, qboolean torso, int oldFrame, int frame, int entNum)
void CG_TriggerAnimSounds (centity_t *cent)
qboolean CG_InRoll (centity_t *cent)
qboolean CG_InRollAnim (centity_t *cent)
qboolean BG_SaberStanceAnim (int anim)
qboolean PM_RunningAnim (int anim)
qboolean PM_WalkingAnim (int anim)
void CG_G2SetBoneAngles (void *ghoul2, int modelIndex, const char *boneName, const vec3_t angles, const int flags, const int up, const int right, const int forward, qhandle_t *modelList, int blendTime, int currentTime)
void CG_Rag_Trace (trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask)
qboolean CG_RagDoll (centity_t *cent, vec3_t forcedAngles)
void CG_G2ServerBoneAngles (centity_t *cent)
qboolean CG_G2PlayerHeadAnims (centity_t *cent)
void CG_AddRefEntityWithPowerups (refEntity_t *ent, entityState_t *state, int team)
void CG_PlayerShieldHit (int entitynum, vec3_t dir, int amount)
void CG_DrawPlayerShield (centity_t *cent, vec3_t origin)
void CG_PlayerHitFX (centity_t *cent)
int CG_LightVerts (vec3_t normal, int numVerts, polyVert_t *verts)
void CG_DoSaber (vec3_t origin, vec3_t dir, float length, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight)
void CG_GetTagWorldPosition (refEntity_t *model, char *tag, vec3_t pos, vec3_t axis[3])
markPoly_tCG_AllocMark ()
void CG_CreateSaberMarks (vec3_t start, vec3_t end, vec3_t normal)
qboolean CG_G2TraceCollide (trace_t *tr, vec3_t const mins, vec3_t const maxs, const vec3_t lastValidStart, const vec3_t lastValidEnd)
void CG_G2SaberEffects (vec3_t start, vec3_t end, centity_t *owner)
void CG_AddGhoul2Mark (int shader, float size, vec3_t start, vec3_t end, int entnum, vec3_t entposition, float entangle, void *ghoul2, vec3_t scale, int lifeTime)
void CG_SaberCompWork (vec3_t start, vec3_t end, centity_t *owner, int saberNum, int bladeNum)
qboolean BG_SuperBreakWinAnim (int anim)
void CG_AddSaberBlade (centity_t *cent, centity_t *scent, refEntity_t *saber, int renderfx, int modelIndex, int saberNum, int bladeNum, vec3_t origin, vec3_t angles, qboolean fromSaber, qboolean dontDraw)
int CG_IsMindTricked (int trickIndex1, int trickIndex2, int trickIndex3, int trickIndex4, int client)
void CG_DrawPlayerSphere (centity_t *cent, vec3_t origin, float scale, int shader)
void CG_AddLightningBeam (vec3_t start, vec3_t end)
void CG_AddRandomLightning (vec3_t start, vec3_t end)
qboolean CG_ThereIsAMaster (void)
int CG_HandleAppendedSkin (char *modelName)
void BG_GetVehicleModelName (char *modelname)
void BG_GetVehicleSkinName (char *skinname)
void CG_CacheG2AnimInfo (char *modelName)
void CG_HandleNPCSounds (centity_t *cent)
void G_CreateAnimalNPC (Vehicle_t **pVeh, const char *strAnimalType)
void G_CreateSpeederNPC (Vehicle_t **pVeh, const char *strType)
void G_CreateWalkerNPC (Vehicle_t **pVeh, const char *strAnimalType)
void G_CreateFighterNPC (Vehicle_t **pVeh, const char *strType)
void CG_G2AnimEntModelLoad (centity_t *cent)
qboolean CG_VehicleShouldDrawShields (centity_t *vehCent)
qboolean CG_VehicleAttachDroidUnit (centity_t *droidCent, refEntity_t *legs)
void CG_G2Animated (centity_t *cent)
void CG_CreateNPCClient (clientInfo_t **ci)
void CG_DestroyNPCClient (clientInfo_t **ci)
void CG_InitJetpackGhoul2 (void)
void CG_CleanJetpackGhoul2 (void)
int BG_EmplacedView (vec3_t baseAngles, vec3_t angles, float *newYaw, float constraint)
float CG_RadiusForCent (centity_t *cent)
void CG_CheckThirdPersonAlpha (centity_t *cent, refEntity_t *legs)
void CG_Player (centity_t *cent)
void CG_ResetPlayerEntity (centity_t *cent)

Variables

vmCvar_t cg_thirdPersonAlpha
int cgSiegeTeam1PlShader
int cgSiegeTeam2PlShader
stringID_table_t animTable [MAX_ANIMATIONS+1]
char * cg_customSoundNames [MAX_CUSTOM_SOUNDS]
const char * cg_customCombatSoundNames [MAX_CUSTOM_COMBAT_SOUNDS]
const char * cg_customExtraSoundNames [MAX_CUSTOM_EXTRA_SOUNDS]
const char * cg_customJediSoundNames [MAX_CUSTOM_JEDI_SOUNDS]
const char * cg_customDuelSoundNames [MAX_CUSTOM_DUEL_SOUNDS]
qboolean cgQueueLoad = qfalse
char * forceHolocronModels []
playerState_tcgSendPS [MAX_GENTITIES]
void * cg_g2JetpackInstance = NULL
int cg_lastHyperSpaceEffectTime = 0
vec3_t cg_crosshairPos
vec3_t cameraCurLoc


Define Documentation

#define CG_MAX_SABER_COMP_TIME   400
 

Definition at line 5736 of file cg_players.c.

Referenced by CG_SaberCompWork().

#define DEFAULT_FEMALE_SOUNDPATH   "chars/mp_generic_female/misc"
 

Definition at line 797 of file cg_players.c.

Referenced by CG_LoadCISounds().

#define DEFAULT_MALE_SOUNDPATH   "chars/mp_generic_male/misc"
 

Definition at line 798 of file cg_players.c.

Referenced by CG_LoadCISounds().

#define FLYBYSOUNDTIME   2000
 

Definition at line 7970 of file cg_players.c.

#define FOOTSTEP_DISTANCE   32
 

Definition at line 1988 of file cg_players.c.

#define FX_USE_ALPHA   0x08000000
 

Definition at line 5987 of file cg_players.c.

#define JETPACK_MODEL   "models/weapons2/jetpack/model.glm"
 

Definition at line 7880 of file cg_players.c.

Referenced by CG_InitJetpackGhoul2().

#define MAX_MARK_FRAGMENTS   128
 

Definition at line 5458 of file cg_players.c.

#define MAX_MARK_POINTS   384
 

Definition at line 5459 of file cg_players.c.

#define MAX_SHIELD_TIME   2000.0
 

Definition at line 5073 of file cg_players.c.

Referenced by CG_PlayerShieldHit().

#define MAX_SURF_LIST_SIZE   1024
 

Definition at line 313 of file cg_players.c.

Referenced by CG_ParseSurfsFile().

#define MIN_SHIELD_TIME   2000.0
 

Definition at line 5074 of file cg_players.c.

Referenced by CG_DrawPlayerShield().

#define RARMBIT   (1 << (G2_MODELPART_RARM-10))
 

Definition at line 7913 of file cg_players.c.

Referenced by CG_Player().

#define REFRACT_EFFECT_DURATION   500
 

Definition at line 4797 of file cg_players.c.

#define RHANDBIT   (1 << (G2_MODELPART_RHAND-10))
 

Definition at line 7914 of file cg_players.c.

Referenced by CG_Player().

#define SABER_TRAIL_TIME   40.0f
 

Definition at line 5986 of file cg_players.c.

Referenced by CG_AddSaberBlade().

#define SHADOW_DISTANCE   128
 

Definition at line 4611 of file cg_players.c.

#define SMOOTH_G2ANIM_LERPANGLES
 

Definition at line 7404 of file cg_players.c.

#define SPEED_TRAIL_DISTANCE   6
 

Definition at line 6520 of file cg_players.c.

Referenced by CG_Player().

#define TURN_OFF   0x00000100
 

Definition at line 21 of file cg_players.c.

Referenced by ATST_Attack(), CG_G2Animated(), GM_Dying(), Mark1_dying(), NPC_BSGM_Default(), NPC_Droid_Pain(), NPC_GalakMech_Init(), NPC_Mark1_Pain(), and NPC_Mark2_Pain().

#define TURN_ON   0x00000000
 

Definition at line 20 of file cg_players.c.

Referenced by CG_G2Animated(), GM_StartGloat(), NPC_BSGM_Default(), NPC_GalakMech_Init(), and NPC_SetSurfaceOnOff().

#define WAISTBIT   (1 << (G2_MODELPART_WAIST-10))
 

Definition at line 7915 of file cg_players.c.

Referenced by CG_Player().


Function Documentation

int BG_EmplacedView vec3_t  baseAngles,
vec3_t  angles,
float *  newYaw,
float  constraint
 

Definition at line 2703 of file bg_misc.c.

02704 {
02705         float dif = AngleSubtract(baseAngles[YAW], angles[YAW]);
02706 
02707         if (dif > constraint ||
02708                 dif < -constraint)
02709         {
02710                 float amt;
02711 
02712                 if (dif > constraint)
02713                 {
02714                         amt = (dif-constraint);
02715                         dif = constraint;
02716                 }
02717                 else if (dif < -constraint)
02718                 {
02719                         amt = (dif+constraint);
02720                         dif = -constraint;
02721                 }
02722                 else
02723                 {
02724                         amt = 0.0f;
02725                 }
02726 
02727                 *newYaw = AngleSubtract(angles[YAW], -dif);
02728 
02729                 if (amt > 1.0f || amt < -1.0f)
02730                 { //significant, force the view
02731                         return 2;
02732                 }
02733                 else
02734                 { //just a little out of range
02735                         return 1;
02736                 }
02737         }
02738 
02739         return 0;
02740 }

void BG_GetVehicleModelName char *  modelname  ) 
 

Definition at line 1599 of file bg_vehicleLoad.c.

01600 {
01601         char *vehName = &modelname[1];
01602         int vIndex = BG_VehicleGetIndex(vehName);
01603         assert(modelname[0] == '$');
01604         
01605         if (vIndex == VEHICLE_NONE)
01606         {
01607                 Com_Error(ERR_DROP, "BG_GetVehicleModelName:  couldn't find vehicle %s", vehName);
01608         }
01609 
01610     strcpy(modelname, g_vehicleInfo[vIndex].model);     
01611 }

void BG_GetVehicleSkinName char *  skinname  ) 
 

Definition at line 1613 of file bg_vehicleLoad.c.

References BG_VehicleGetIndex(), Com_Error(), ERR_DROP, g_vehicleInfo, vehicleInfo_t::skin, strcpy(), and VEHICLE_NONE.

Referenced by CG_CacheG2AnimInfo().

01614 {
01615         char *vehName = &skinname[1];
01616         int vIndex = BG_VehicleGetIndex(vehName);
01617         assert(skinname[0] == '$');
01618         
01619         if (vIndex == VEHICLE_NONE)
01620         {
01621                 Com_Error(ERR_DROP, "BG_GetVehicleSkinName:  couldn't find vehicle %s", vehName);
01622         }
01623 
01624     if ( !g_vehicleInfo[vIndex].skin 
01625                 || !g_vehicleInfo[vIndex].skin[0] )
01626         {
01627                 skinname[0] = 0;
01628         }
01629         else
01630         {
01631                 strcpy(skinname, g_vehicleInfo[vIndex].skin);   
01632         }
01633 }

qboolean BG_IsValidCharacterModel const char *  modelName,
const char *  skinName
 

Definition at line 2744 of file bg_misc.c.

02745 {
02746         if (!Q_stricmp(skinName, "menu"))
02747         {
02748                 return qfalse;
02749         }
02750         else if (!Q_stricmp(modelName, "kyle"))
02751         {
02752                 if (!Q_stricmp(skinName, "fpls"))
02753                 {
02754                         return qfalse;
02755                 }
02756                 else if (!Q_stricmp(skinName, "fpls2"))
02757                 {
02758                         return qfalse;
02759                 }
02760                 else if (!Q_stricmp(skinName, "fpls3"))
02761                 {
02762                         return qfalse;
02763                 }
02764         }
02765         return qtrue;
02766 }

qboolean BG_SaberStanceAnim int  anim  ) 
 

Definition at line 33 of file bg_panimate.c.

00034 {
00035         switch ( anim )
00036         {
00037         case BOTH_STAND1://not really a saberstance anim, actually... "saber off" stance
00038         case BOTH_STAND2://single-saber, medium style
00039         case BOTH_SABERFAST_STANCE://single-saber, fast style
00040         case BOTH_SABERSLOW_STANCE://single-saber, strong style
00041         case BOTH_SABERSTAFF_STANCE://saber staff style
00042         case BOTH_SABERDUAL_STANCE://dual saber style
00043                 return qtrue;
00044                 break;
00045         }
00046         return qfalse;
00047 }

qboolean BG_SuperBreakWinAnim int  anim  ) 
 

Definition at line 1458 of file bg_panimate.c.

01459 {
01460         switch ( anim )
01461         {
01462         case BOTH_LK_S_DL_S_SB_1_W:     //super break I won
01463         case BOTH_LK_S_DL_T_SB_1_W:     //super break I won
01464         case BOTH_LK_S_ST_S_SB_1_W:     //super break I won
01465         case BOTH_LK_S_ST_T_SB_1_W:     //super break I won
01466         case BOTH_LK_S_S_S_SB_1_W:      //super break I won
01467         case BOTH_LK_S_S_T_SB_1_W:      //super break I won
01468         case BOTH_LK_DL_DL_S_SB_1_W:    //super break I won
01469         case BOTH_LK_DL_DL_T_SB_1_W:    //super break I won
01470         case BOTH_LK_DL_ST_S_SB_1_W:    //super break I won
01471         case BOTH_LK_DL_ST_T_SB_1_W:    //super break I won
01472         case BOTH_LK_DL_S_S_SB_1_W:     //super break I won
01473         case BOTH_LK_DL_S_T_SB_1_W:     //super break I won
01474         case BOTH_LK_ST_DL_S_SB_1_W:    //super break I won
01475         case BOTH_LK_ST_DL_T_SB_1_W:    //super break I won
01476         case BOTH_LK_ST_ST_S_SB_1_W:    //super break I won
01477         case BOTH_LK_ST_ST_T_SB_1_W:    //super break I won
01478         case BOTH_LK_ST_S_S_SB_1_W:     //super break I won
01479         case BOTH_LK_ST_S_T_SB_1_W:     //super break I won
01480                 return qtrue;
01481                 break;
01482         }
01483         return qfalse;
01484 }

qboolean BG_ValidateSkinForTeam const char *  modelName,
char *  skinName,
int  team,
float *  colors
 

Definition at line 2768 of file bg_misc.c.

02769 {
02770         if (!Q_stricmpn(modelName, "jedi_",5))
02771         { //argh, it's a custom player skin!
02772                 if (team == TEAM_RED && colors)
02773                 {
02774                         colors[0] = 1.0f;
02775                         colors[1] = 0.0f;
02776                         colors[2] = 0.0f;
02777                 }
02778                 else if (team == TEAM_BLUE && colors)
02779                 {
02780                         colors[0] = 0.0f;
02781                         colors[1] = 0.0f;
02782                         colors[2] = 1.0f;
02783                 }
02784                 return qtrue;
02785         }
02786 
02787         if (team == TEAM_RED)
02788         {
02789                 if ( Q_stricmp( "red", skinName ) != 0 )
02790                 {//not "red"
02791                         if ( Q_stricmp( "blue", skinName ) == 0
02792                                 || Q_stricmp( "default", skinName ) == 0
02793                                 || strchr(skinName, '|')//a multi-skin playerModel
02794                                 || !BG_IsValidCharacterModel(modelName, skinName) )
02795                         {
02796                                 Q_strncpyz(skinName, "red", MAX_QPATH);
02797                                 return qfalse;
02798                         }
02799                         else
02800                         {//need to set it to red
02801                                 int len = strlen( skinName );
02802                                 if ( len < 3 )
02803                                 {//too short to be "red"
02804                                         Q_strcat(skinName, MAX_QPATH, "_red");
02805                                 }
02806                                 else
02807                                 {
02808                                         char    *start = &skinName[len-3];
02809                                         if ( Q_strncmp( "red", start, 3 ) != 0 )
02810                                         {//doesn't already end in "red"
02811                                                 if ( len+4 >= MAX_QPATH )
02812                                                 {//too big to append "_red"
02813                                                         Q_strncpyz(skinName, "red", MAX_QPATH);
02814                                                         return qfalse;
02815                                                 }
02816                                                 else
02817                                                 {
02818                                                         Q_strcat(skinName, MAX_QPATH, "_red");
02819                                                 }
02820                                         }
02821                                 }
02822                                 //if file does not exist, set to "red"
02823                                 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02824                                 {
02825                                         Q_strncpyz(skinName, "red", MAX_QPATH);
02826                                 }
02827                                 return qfalse;
02828                         }
02829                 }
02830 
02831         }
02832         else if (team == TEAM_BLUE)
02833         {
02834                 if ( Q_stricmp( "blue", skinName ) != 0 )
02835                 {
02836                         if ( Q_stricmp( "red", skinName ) == 0
02837                                 || Q_stricmp( "default", skinName ) == 0
02838                                 || strchr(skinName, '|')//a multi-skin playerModel
02839                                 || !BG_IsValidCharacterModel(modelName, skinName) )
02840                         {
02841                                 Q_strncpyz(skinName, "blue", MAX_QPATH);
02842                                 return qfalse;
02843                         }
02844                         else
02845                         {//need to set it to blue
02846                                 int len = strlen( skinName );
02847                                 if ( len < 4 )
02848                                 {//too short to be "blue"
02849                                         Q_strcat(skinName, MAX_QPATH, "_blue");
02850                                 }
02851                                 else 
02852                                 {
02853                                         char    *start = &skinName[len-4];
02854                                         if ( Q_strncmp( "blue", start, 4 ) != 0 )
02855                                         {//doesn't already end in "blue"
02856                                                 if ( len+5 >= MAX_QPATH )
02857                                                 {//too big to append "_blue"
02858                                                         Q_strncpyz(skinName, "blue", MAX_QPATH);
02859                                                         return qfalse;
02860                                                 }
02861                                                 else
02862                                                 {
02863                                                         Q_strcat(skinName, MAX_QPATH, "_blue");
02864                                                 }
02865                                         }
02866                                 }
02867                                 //if file does not exist, set to "blue"
02868                                 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02869                                 {
02870                                         Q_strncpyz(skinName, "blue", MAX_QPATH);
02871                                 }
02872                                 return qfalse;
02873                         }
02874                 }
02875         }
02876         return qtrue;
02877 }

void CG_ActualLoadDeferredPlayers void   ) 
 

Definition at line 1953 of file cg_players.c.

References CG_LoadClientInfo(), cgs, cgs_t::clientinfo, and cgs_t::maxclients.

Referenced by CG_DrawActiveFrame().

01954 {
01955         int             i;
01956         clientInfo_t    *ci;
01957 
01958         // scan for a deferred player to load
01959         for ( i = 0, ci = cgs.clientinfo ; i < cgs.maxclients ; i++, ci++ ) {
01960                 if ( ci->infoValid && ci->deferred ) {
01961                         CG_LoadClientInfo( ci );
01962 //                      break;
01963                 }
01964         }
01965 }

void CG_AddBracketedEnt centity_t cent  ) 
 

Definition at line 811 of file cg_ents.c.

References cg_t::bracketedEntities, cg_t::bracketedEntityCount, centity_t, cg, Com_Printf(), centity_s::currentState, entityState_s::number, and cg_t::radarEntities.

Referenced by CG_Player().

00812 {
00813         if (cg.bracketedEntityCount == sizeof(cg.bracketedEntities)/sizeof(cg.bracketedEntities[0]))
00814         {       
00815 #ifdef _DEBUG
00816                 Com_Printf("^3Warning: CG_AddBracketedEnt full. (%d max)\n", sizeof(cg.radarEntities)/sizeof(cg.bracketedEntities[0]));
00817 #endif
00818                 return;
00819         }
00820         cg.bracketedEntities[cg.bracketedEntityCount++] = cent->currentState.number;
00821 }

void CG_AddGhoul2Mark int  shader,
float  size,
vec3_t  start,
vec3_t  end,
int  entnum,
vec3_t  entposition,
float  entangle,
void *  ghoul2,
vec3_t  scale,
int  lifeTime
 

Definition at line 5738 of file cg_players.c.

References SSkinGoreData_s::angles, SSkinGoreData_s::backFaces, SSkinGoreData_s::baseModelOnly, cg, cg_ghoul2Marks, SSkinGoreData_s::currentTime, SSkinGoreData_s::entNum, flrand(), SSkinGoreData_s::frontFaces, SSkinGoreData_s::goreScaleStartFraction, SSkinGoreData_s::growDuration, SSkinGoreData_s::hitLocation, vmCvar_t::integer, SSkinGoreData_s::lifeTime, memset(), SSkinGoreData_s::position, qfalse, qtrue, SSkinGoreData_s::rayDirection, SSkinGoreData_s::scale, SSkinGoreData_s::shader, SSkinGoreData_s::SSize, SSkinGoreData, SSkinGoreData_s::theta, cg_t::time, trap_G2API_AddSkinGore(), trap_G2API_GetNumGoreMarks(), SSkinGoreData_s::TSize, vec3_t, VectorCopy, VectorNormalize(), VectorSet, VectorSubtract, and YAW.

Referenced by CG_G2MarkEvent(), and CG_SaberCompWork().

05740 {
05741         SSkinGoreData goreSkin;
05742 
05743         assert(ghoul2);
05744 
05745         memset ( &goreSkin, 0, sizeof(goreSkin) );
05746 
05747         if (trap_G2API_GetNumGoreMarks(ghoul2, 0) >= cg_ghoul2Marks.integer)
05748         { //you've got too many marks already
05749                 return;
05750         }
05751 
05752         goreSkin.growDuration = -1; // default expandy time
05753         goreSkin.goreScaleStartFraction = 1.0; // default start scale
05754         goreSkin.frontFaces = qtrue;
05755         goreSkin.backFaces = qtrue;
05756         goreSkin.lifeTime = lifeTime; //last randomly 10-20 seconds
05757         /*
05758         if (lifeTime)
05759         {
05760                 goreSkin.fadeOutTime = lifeTime*0.1; //default fade duration is relative to lifetime.
05761         }
05762         goreSkin.fadeRGB = qtrue; //fade on RGB instead of alpha (this depends on the shader really, modify if needed)
05763         */
05764         //rwwFIXMEFIXME: fade has sorting issues with other non-fading decals, disabled until fixed
05765 
05766         goreSkin.baseModelOnly = qfalse;
05767         
05768         goreSkin.currentTime = cg.time;
05769         goreSkin.entNum      = entnum;
05770         goreSkin.SSize           = size;
05771         goreSkin.TSize           = size;
05772         goreSkin.theta           = flrand(0.0f,6.28f);
05773         goreSkin.shader          = shader;
05774 
05775         if (!scale[0] && !scale[1] && !scale[2])
05776         {
05777                 VectorSet(goreSkin.scale, 1.0f, 1.0f, 1.0f);
05778         }
05779         else
05780         {
05781                 VectorCopy(goreSkin.scale, scale);
05782         }
05783 
05784         VectorCopy (start, goreSkin.hitLocation);
05785 
05786         VectorSubtract(end, start, goreSkin.rayDirection);
05787         if (VectorNormalize(goreSkin.rayDirection)<.1f)
05788         {
05789                 return;
05790         }
05791 
05792         VectorCopy ( entposition, goreSkin.position );
05793         goreSkin.angles[YAW] = entangle;
05794 
05795         trap_G2API_AddSkinGore(ghoul2, &goreSkin);
05796 }

void CG_AddLightningBeam vec3_t  start,
vec3_t  end
 

Definition at line 6628 of file cg_players.c.

References addbezierArgStruct_t, addbezierArgStruct_s::alpha1, addbezierArgStruct_s::alpha2, addbezierArgStruct_s::alphaParm, cg, addbezierArgStruct_s::control1, addbezierArgStruct_s::control1Vel, addbezierArgStruct_s::control2, addbezierArgStruct_s::control2Vel, crandom, addbezierArgStruct_s::end, addbezierArgStruct_s::eRGB, addbezierArgStruct_s::flags, addbezierArgStruct_s::killTime, addbezierArgStruct_s::rgbParm, addbezierArgStruct_s::shader, sin(), addbezierArgStruct_s::size1, addbezierArgStruct_s::size2, addbezierArgStruct_s::sizeParm, addbezierArgStruct_s::sRGB, addbezierArgStruct_s::start, cg_t::time, trap_FX_AddBezier(), trap_R_RegisterShader(), vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSet, and VectorSubtract.

Referenced by CG_AddRandomLightning().

06629 {
06630         vec3_t  dir, chaos,
06631                         c1, c2,
06632                         v1, v2;
06633         float   len,
06634                         s1, s2, s3;
06635 
06636         addbezierArgStruct_t b;
06637 
06638         VectorCopy(start, b.start);
06639         VectorCopy(end, b.end);
06640 
06641         VectorSubtract( b.end, b.start, dir );
06642         len = VectorNormalize( dir );
06643 
06644         // Get the base control points, we'll work from there
06645         VectorMA( b.start, 0.3333f * len, dir, c1 );
06646         VectorMA( b.start, 0.6666f * len, dir, c2 );
06647 
06648         // get some chaos values that really aren't very chaotic :)
06649         s1 = sin( cg.time * 0.005f ) * 2 + crandom() * 0.2f;
06650         s2 = sin( cg.time * 0.001f );
06651         s3 = sin( cg.time * 0.011f );
06652 
06653         VectorSet( chaos, len * 0.01f * s1,
06654                                                 len * 0.02f * s2,
06655                                                 len * 0.04f * (s1 + s2 + s3));
06656 
06657         VectorAdd( c1, chaos, c1 );
06658         VectorScale( chaos, 4.0f, v1 );
06659 
06660         VectorSet( chaos, -len * 0.02f * s3,
06661                                                 len * 0.01f * (s1 * s2),
06662                                                 -len * 0.02f * (s1 + s2 * s3));
06663 
06664         VectorAdd( c2, chaos, c2 );
06665         VectorScale( chaos, 2.0f, v2 );
06666 
06667         VectorSet( chaos, 1.0f, 1.0f, 1.0f );
06668 
06669         VectorCopy(c1, b.control1);
06670         VectorCopy(vec3_origin, b.control1Vel);
06671         VectorCopy(c2, b.control2);
06672         VectorCopy(vec3_origin, b.control2Vel);
06673 
06674         b.size1 = 6.0f;
06675         b.size2 = 6.0f;
06676         b.sizeParm = 0.0f;
06677         b.alpha1 = 0.0f;
06678         b.alpha2 = 0.2f;
06679         b.alphaParm = 0.5f;
06680         
06681         /*
06682         VectorCopy(WHITE, b.sRGB);
06683         VectorCopy(WHITE, b.eRGB);
06684         */
06685 
06686         b.sRGB[0] = 255;
06687         b.sRGB[1] = 255;
06688         b.sRGB[2] = 255;
06689         VectorCopy(b.sRGB, b.eRGB);
06690 
06691         b.rgbParm = 0.0f;
06692         b.killTime = 50;
06693         b.shader = trap_R_RegisterShader( "gfx/misc/electric2" );
06694         b.flags = 0x00000001; //FX_ALPHA_LINEAR
06695 
06696         trap_FX_AddBezier(&b);
06697 }

void CG_AddRadarEnt centity_t cent  ) 
 

Definition at line 799 of file cg_ents.c.

References centity_t, cg, Com_Printf(), centity_s::currentState, entityState_s::number, cg_t::radarEntities, and cg_t::radarEntityCount.

Referenced by CG_Player().

00800 {
00801         if (cg.radarEntityCount == sizeof(cg.radarEntities)/sizeof(cg.radarEntities[0]))
00802         {       
00803 #ifdef _DEBUG
00804                 Com_Printf("^3Warning: CG_AddRadarEnt full. (%d max)\n", sizeof(cg.radarEntities)/sizeof(cg.radarEntities[0]));
00805 #endif
00806                 return;
00807         }
00808         cg.radarEntities[cg.radarEntityCount++] = cent->currentState.number;
00809 }

void CG_AddRandomLightning vec3_t  start,
vec3_t  end
 

Definition at line 6699 of file cg_players.c.

References CG_AddLightningBeam(), Q_irand(), rand(), vec3_t, and VectorCopy.

06700 {
06701         vec3_t inOrg, outOrg;
06702 
06703         VectorCopy(start, inOrg);
06704         VectorCopy(end, outOrg);
06705 
06706         if ( rand() & 1 )
06707         {
06708                 outOrg[0] += Q_irand(0, 24);
06709                 inOrg[0] += Q_irand(0, 8);
06710         }
06711         else
06712         {
06713                 outOrg[0] -= Q_irand(0, 24);
06714                 inOrg[0] -= Q_irand(0, 8);
06715         }
06716 
06717         if ( rand() & 1 )
06718         {
06719                 outOrg[1] += Q_irand(0, 24);
06720                 inOrg[1] += Q_irand(0, 8);
06721         }
06722         else
06723         {
06724                 outOrg[1] -= Q_irand(0, 24);
06725                 inOrg[1] -= Q_irand(0, 8);
06726         }
06727 
06728         if ( rand() & 1 )
06729         {
06730                 outOrg[2] += Q_irand(0, 50);
06731                 inOrg[2] += Q_irand(0, 40);
06732         }
06733         else
06734         {
06735                 outOrg[2] -= Q_irand(0, 64);
06736                 inOrg[2] -= Q_irand(0, 40);
06737         }
06738 
06739         CG_AddLightningBeam(inOrg, outOrg);
06740 }

void CG_AddRefEntityWithPowerups refEntity_t ent,
entityState_t state,
int  team
 

Definition at line 5059 of file cg_players.c.

References cg, CG_IsMindTricked(), playerState_s::clientNum, entityState_t, snapshot_t::ps, cg_t::snap, trap_R_AddRefEntityToScene(), entityState_s::trickedentindex, entityState_s::trickedentindex2, entityState_s::trickedentindex3, and entityState_s::trickedentindex4.

05059                                                                                      {
05060 
05061         if (CG_IsMindTricked(state->trickedentindex,
05062                 state->trickedentindex2,
05063                 state->trickedentindex3,
05064                 state->trickedentindex4,
05065                 cg.snap->ps.clientNum))
05066         {
05067                 return; //this entity is mind-tricking the current client, so don't render it
05068         }
05069 
05070         trap_R_AddRefEntityToScene( ent );
05071 }

void CG_AddSaberBlade centity_t cent,
centity_t scent,
refEntity_t saber,
int  renderfx,
int  modelIndex,
int  saberNum,
int  bladeNum,
vec3_t  origin,
vec3_t  angles,
qboolean  fromSaber,
qboolean  dontDraw
 

Definition at line 5993 of file cg_players.c.

References effectTrailVertStruct_t::alpha, entityState_s::apos, saberTrail_t::base, BG_SaberInAttack(), BG_SuperBreakWinAnim(), saberInfo_t::blade, saberInfo_t::bladeEffect, saberInfo_t::bladeEffect2, centity_t, cg, CG_CreateSaberMarks(), CG_DoSaber(), cg_entities, CG_G2SaberEffects(), cg_saberClientVisualCompensation, CG_SaberCompWork(), cg_saberContact, cg_saberModelTraceEffect, cg_saberTrail, cg_shadows, cg_speedTrail, CG_Trace(), cgs, CHAN_WEAPON, client, cgs_t::clientinfo, bladeInfo_t::color, centity_s::currentState, effectTrailVertStruct_t::destST, saberTrail_t::duration, EF_PERMANENT, cgs_t::effects, effectTrailArgStruct_t, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, ET_NPC, ET_TERRAIN, entityState_s::eType, trace_t::fraction, FX_USE_ALPHA, cgs_t::gameModels, cgs_t::gametype, centity_s::ghoul2, cgs_t::glconfig, GT_SIEGE, GT_TEAM, saberTrail_t::haveOldPos, bladeInfo_t::hitWallDebounceTime, vmCvar_t::integer, cgs_t::jediVmerc, saberTrail_t::lastTime, bladeInfo_t::length, bladeInfo_t::lengthMax, centity_s::lerpOrigin, MASK_SOLID, cgs_t::media, effectTrailArgStruct_s::mKillTime, centity_s::modelScale, polyVert_t::modulate, effectTrailArgStruct_s::mSetFlags, effectTrailArgStruct_s::mShader, cgEffects_t::mSparks, effectTrailArgStruct_s::mVerts, NEGATIVE_Y, cplane_s::normal, centity_s::npcClient, NULL, entityState_s::number, saberInfo_t::numBlades, saberTrail_t::oldNormal, saberTrail_t::oldPos, effectTrailVertStruct_t::origin, ORIGIN, PITCH, trace_t::plane, entityState_s::pos, entityState_s::powerups, PW_SPEED, Q_irand(), qboolean, qfalse, qtrue, bladeInfo_t::radius, effectTrailVertStruct_t::rgb, ROLL, gclient_s::saber, SABER_BLUE, SABER_GREEN, SABER_ORANGE, SABER_PURPLE, SABER_RED, SABER_TRAIL_TIME, SABER_YELLOW, cgMedia_t::saberBlurShader, entityState_s::saberEntityNum, saberInfo_t::saberFlags2, entityState_s::saberInFlight, entityState_s::saberMove, saberMoveData, SFL2_NO_BLADE, SFL2_NO_DLIGHT, SFL2_NO_WALL_MARKS, effectTrailVertStruct_t::ST, polyVert_t::st, glconfig_t::stencilBits, bladeInfo_t::storageTime, SURF_NOIMPACT, trace_t::surfaceFlags, cgMedia_t::swordTrailShader, TEAM_BLUE, TEAM_RED, cg_t::time, saberTrail_t::tip, entityState_s::torsoAnim, bladeInfo_t::trail, saberInfo_t::trailStyle, saberInfo_t::trailStyle2, trap_FX_AddPrimitive(), trap_FX_PlayBoltedEffectID(), trap_FX_PlayEffectID(), trap_G2API_GetBoltMatrix(), trap_R_AddPolyToScene(), trap_R_SetRefractProp(), trap_S_RegisterSound(), trap_S_StartSound(), trajectory_t::trBase, va(), vec3_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorSet, VectorSubtract, WP_SaberBladeUseSecondBladeStyle(), polyVert_t::xyz, and YAW.

Referenced by CG_Player().

05994 {
05995         vec3_t  org_, end, v,
05996                         axis_[3] = {0,0,0, 0,0,0, 0,0,0};       // shut the compiler up
05997         trace_t trace;
05998         int i = 0;
05999         int trailDur;
06000         float saberLen;
06001         float diff;
06002         clientInfo_t *client;
06003         centity_t *saberEnt;
06004         saberTrail_t *saberTrail;
06005         mdxaBone_t      boltMatrix;
06006         vec3_t futureAngles;
06007         effectTrailArgStruct_t fx;
06008         int scolor = 0;
06009         int     useModelIndex = 0;
06010 
06011         if (cent->currentState.eType == ET_NPC)
06012         {
06013                 client = cent->npcClient;
06014                 assert(client);
06015         }
06016         else
06017         {
06018                 client = &cgs.clientinfo[cent->currentState.number];
06019         }
06020 
06021         saberEnt = &cg_entities[cent->currentState.saberEntityNum];
06022         saberLen = client->saber[saberNum].blade[bladeNum].length;
06023 
06024         if (saberLen <= 0 && !dontDraw)
06025         { //don't bother then.
06026                 return;
06027         }
06028 
06029         futureAngles[YAW] = angles[YAW];
06030         futureAngles[PITCH] = angles[PITCH];
06031         futureAngles[ROLL] = angles[ROLL];
06032 
06033 
06034         if ( fromSaber )
06035         {
06036                 useModelIndex = 0;
06037         }
06038         else
06039         {
06040                 useModelIndex = saberNum+1;
06041         }
06042         //Assume bladeNum is equal to the bolt index because bolts should be added in order of the blades.
06043         //if there is an effect on this blade, play it
06044         if (  !WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum )
06045                         && client->saber[saberNum].bladeEffect )
06046         {
06047                 trap_FX_PlayBoltedEffectID(client->saber[saberNum].bladeEffect, scent->lerpOrigin, 
06048                         scent->ghoul2, bladeNum, scent->currentState.number, useModelIndex, -1, qfalse);
06049         }
06050         else if ( WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum )
06051                         && client->saber[saberNum].bladeEffect2 )
06052         {
06053                 trap_FX_PlayBoltedEffectID(client->saber[saberNum].bladeEffect2, scent->lerpOrigin, 
06054                         scent->ghoul2, bladeNum, scent->currentState.number, useModelIndex, -1, qfalse);
06055         }
06056         //get the boltMatrix
06057         trap_G2API_GetBoltMatrix(scent->ghoul2, useModelIndex, bladeNum, &boltMatrix, futureAngles, origin, cg.time, cgs.gameModels, scent->modelScale);
06058 
06059         // work the matrix axis stuff into the original axis and origins used.
06060         BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, org_);
06061         BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_Y, axis_[0]);
06062 
06063         if (!fromSaber && saberEnt && !cent->currentState.saberInFlight)
06064         {
06065                 VectorCopy(org_, saberEnt->currentState.pos.trBase);
06066 
06067                 VectorCopy(axis_[0], saberEnt->currentState.apos.trBase);
06068         }
06069 
06070         VectorMA( org_, saberLen, axis_[0], end );
06071         
06072         VectorAdd( end, axis_[0], end );
06073 
06074         if (cent->currentState.eType == ET_NPC)
06075         {
06076                 scolor = client->saber[saberNum].blade[bladeNum].color;
06077         }
06078         else
06079         {
06080                 if (saberNum == 0)
06081                 {
06082                         scolor = client->icolor1;
06083                 }
06084                 else
06085                 {
06086                         scolor = client->icolor2;
06087                 }
06088         }
06089 
06090         if (cgs.gametype >= GT_TEAM &&
06091                 cgs.gametype != GT_SIEGE &&
06092                 !cgs.jediVmerc &&
06093                 cent->currentState.eType != ET_NPC)
06094         {
06095                 if (client->team == TEAM_RED)
06096                 {
06097                         scolor = SABER_RED;
06098                 }
06099                 else if (client->team == TEAM_BLUE)
06100                 {
06101                         scolor = SABER_BLUE;
06102                 }
06103         }
06104 
06105         if (!cg_saberContact.integer)
06106         { //if we don't have saber contact enabled, just add the blade and don't care what it's touching
06107                 goto CheckTrail;
06108         }
06109 
06110         if (!dontDraw)
06111         {
06112                 if (cg_saberModelTraceEffect.integer)
06113                 {
06114                         CG_G2SaberEffects(org_, end, cent);
06115                 }
06116                 else if (cg_saberClientVisualCompensation.integer)
06117                 {
06118                         CG_Trace( &trace, org_, NULL, NULL, end, ENTITYNUM_NONE, MASK_SOLID );
06119 
06120                         if (trace.fraction != 1)
06121                         { //nudge the endpos a very small amount from the beginning to the end, so the comp trace hits at the end.
06122                         //I'm only bothering with this because I want to do a backwards trace too in the comp trace, so if the
06123                         //blade is sticking through a player or something the standard trace doesn't it, it will make sparks
06124                         //on each side.
06125                                 vec3_t seDif;
06126 
06127                                 VectorSubtract(trace.endpos, org_, seDif);
06128                                 VectorNormalize(seDif);
06129                                 trace.endpos[0] += seDif[0]*0.1f;
06130                                 trace.endpos[1] += seDif[1]*0.1f;
06131                                 trace.endpos[2] += seDif[2]*0.1f;
06132                         }
06133 
06134                         if (client->saber[saberNum].blade[bladeNum].storageTime < cg.time)
06135                         { //debounce it in case our framerate is absurdly high. Using storageTime since it's not used for anything else in the client.
06136                                 CG_SaberCompWork(org_, trace.endpos, cent, saberNum, bladeNum);
06137 
06138                                 client->saber[saberNum].blade[bladeNum].storageTime = cg.time + 5;
06139                         }
06140                 }
06141 
06142                 for ( i = 0; i < 1; i++ )//was 2 because it would go through architecture and leave saber trails on either side of the brush - but still looks bad if we hit a corner, blade is still 8 longer than hit
06143                 {
06144                         if ( i )
06145                         {//tracing from end to base
06146                                 CG_Trace( &trace, end, NULL, NULL, org_, ENTITYNUM_NONE, MASK_SOLID );
06147                         }
06148                         else
06149                         {//tracing from base to end
06150                                 CG_Trace( &trace, org_, NULL, NULL, end, ENTITYNUM_NONE, MASK_SOLID );
06151                         }
06152                         
06153                         if ( trace.fraction < 1.0f )
06154                         {
06155                                 vec3_t trDir;
06156                                 VectorCopy(trace.plane.normal, trDir);
06157                                 if (!trDir[0] && !trDir[1] && !trDir[2])
06158                                 {
06159                                         trDir[1] = 1;
06160                                 }
06161 
06162                                 if ( (client->saber[saberNum].saberFlags2&SFL2_NO_WALL_MARKS) )
06163                                 {//don't actually draw the marks/impact effects
06164                                 }
06165                                 else
06166                                 {
06167                                         if (!(trace.surfaceFlags & SURF_NOIMPACT) ) // never spark on sky
06168                                         {
06169                                                 trap_FX_PlayEffectID( cgs.effects.mSparks, trace.endpos, trDir, -1, -1 );
06170                                         }
06171                                 }
06172 
06173                                 //Stop saber? (it wouldn't look right if it was stuck through a thin wall and unable to hurt players on the other side)
06174                                 VectorSubtract(org_, trace.endpos, v);
06175                                 saberLen = VectorLength(v);
06176 
06177                                 VectorCopy(trace.endpos, end);
06178 
06179                                 if ( (client->saber[saberNum].saberFlags2&SFL2_NO_WALL_MARKS) )
06180                                 {//don't actually draw the marks
06181                                 }
06182                                 else
06183                                 {//draw marks if we hit a wall
06184                                         // All I need is a bool to mark whether I have a previous point to work with.
06185                                         //....come up with something better..
06186                                         if ( client->saber[saberNum].blade[bladeNum].trail.haveOldPos[i] )
06187                                         {
06188                                                 if ( trace.entityNum == ENTITYNUM_WORLD || cg_entities[trace.entityNum].currentState.eType == ET_TERRAIN || (cg_entities[trace.entityNum].currentState.eFlags & EF_PERMANENT) )
06189                                                 {//only put marks on architecture
06190                                                         // Let's do some cool burn/glowing mark bits!!!
06191                                                         CG_CreateSaberMarks( client->saber[saberNum].blade[bladeNum].trail.oldPos[i], trace.endpos, trace.plane.normal );
06192                                                 
06193                                                         //make a sound
06194                                                         if ( cg.time - client->saber[saberNum].blade[bladeNum].hitWallDebounceTime >= 100 )
06195                                                         {//ugh, need to have a real sound debouncer... or do this game-side
06196                                                                 client->saber[saberNum].blade[bladeNum].hitWallDebounceTime = cg.time;
06197                                                                 trap_S_StartSound ( trace.endpos, -1, CHAN_WEAPON, trap_S_RegisterSound( va("sound/weapons/saber/saberhitwall%i", Q_irand(1, 3)) ) );
06198                                                         }
06199                                                 }
06200                                         }
06201                                         else
06202                                         {
06203                                                 // if we impact next frame, we'll mark a slash mark
06204                                                 client->saber[saberNum].blade[bladeNum].trail.haveOldPos[i] = qtrue;
06205                 //                              CG_ImpactMark( cgs.media.rivetMarkShader, client->saber[saberNum].blade[bladeNum].trail.oldPos[i], client->saber[saberNum].blade[bladeNum].trail.oldNormal[i],
06206                 //                                              0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, 1.1f, qfalse );
06207                                         }
06208                                 }
06209 
06210                                 // stash point so we can connect-the-dots later
06211                                 VectorCopy( trace.endpos, client->saber[saberNum].blade[bladeNum].trail.oldPos[i] );
06212                                 VectorCopy( trace.plane.normal, client->saber[saberNum].blade[bladeNum].trail.oldNormal[i] );
06213                         }
06214                         else
06215                         {
06216                                 if ( client->saber[saberNum].blade[bladeNum].trail.haveOldPos[i] )
06217                                 {
06218                                         // Hmmm, no impact this frame, but we have an old point
06219                                         // Let's put the mark there, we should use an endcap mark to close the line, but we 
06220                                         //      can probably just get away with a round mark
06221         //                                      CG_ImpactMark( cgs.media.rivetMarkShader, client->saber[saberNum].blade[bladeNum].trail.oldPos[i], client->saber[saberNum].blade[bladeNum].trail.oldNormal[i],
06222         //                                                      0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, 1.1f, qfalse );
06223                                 }
06224 
06225                                 // we aren't impacting, so turn off our mark tracking mechanism
06226                                 client->saber[saberNum].blade[bladeNum].trail.haveOldPos[i] = qfalse;
06227                         }
06228                 }
06229         }
06230 CheckTrail:
06231 
06232         if (!cg_saberTrail.integer)
06233         { //don't do the trail in this case
06234                 goto JustDoIt;
06235         }
06236 
06237         if ( (!WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum ) && client->saber[saberNum].trailStyle > 1 )
06238                  || ( WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum ) && client->saber[saberNum].trailStyle2 > 1 ) )
06239         {//don't actually draw the trail at all
06240                 goto JustDoIt;
06241         }
06242 
06243         //FIXME: if trailStyle is 1, use the motion blur instead
06244 
06245         saberTrail = &client->saber[saberNum].blade[bladeNum].trail;
06246         saberTrail->duration = saberMoveData[cent->currentState.saberMove].trailLength;
06247 
06248         trailDur = (saberTrail->duration/5.0f);
06249         if (!trailDur)
06250         { //hmm.. ok, default
06251                 if ( BG_SuperBreakWinAnim(cent->currentState.torsoAnim) )
06252                 {
06253                         trailDur = 150;
06254                 }
06255                 else
06256                 {
06257                         trailDur = SABER_TRAIL_TIME;
06258                 }
06259         }
06260 
06261         // if we happen to be timescaled or running in a high framerate situation, we don't want to flood
06262         //      the system with very small trail slices...but perhaps doing it by distance would yield better results?
06263         if ( cg.time > saberTrail->lastTime + 2 || cg_saberTrail.integer == 2 ) // 2ms
06264         {
06265                 if (!dontDraw)
06266                 {
06267                         if ( (BG_SuperBreakWinAnim(cent->currentState.torsoAnim) || saberMoveData[cent->currentState.saberMove].trailLength > 0 || ((cent->currentState.powerups & (1 << PW_SPEED) && cg_speedTrail.integer)) || (cent->currentState.saberInFlight && saberNum == 0)) && cg.time < saberTrail->lastTime + 2000 ) // if we have a stale segment, don't draw until we have a fresh one
06268                         {
06269         #if 0
06270                                 if (cg_saberTrail.integer == 2 && cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4)
06271                                 {
06272                                         polyVert_t      verts[4];
06273 
06274                                         VectorCopy( org_, verts[0].xyz );
06275                                         VectorMA( end, 3.0f, axis_[0], verts[1].xyz );
06276                                         VectorCopy( saberTrail->tip, verts[2].xyz );
06277                                         VectorCopy( saberTrail->base, verts[3].xyz );
06278 
06279                                         //tc doesn't even matter since we're just gonna stencil an outline, but whatever.
06280                                         verts[0].st[0] = 0;     
06281                                         verts[0].st[1] = 0;     
06282                                         verts[0].modulate[0] = 255;     
06283                                         verts[0].modulate[1] = 255;     
06284                                         verts[0].modulate[2] = 255;     
06285                                         verts[0].modulate[3] = 255;
06286 
06287                                         verts[1].st[0] = 0;     
06288                                         verts[1].st[1] = 1;     
06289                                         verts[1].modulate[0] = 255;     
06290                                         verts[1].modulate[1] = 255;     
06291                                         verts[1].modulate[2] = 255;     
06292                                         verts[1].modulate[3] = 255;
06293 
06294                                         verts[2].st[0] = 1;     
06295                                         verts[2].st[1] = 1;     
06296                                         verts[2].modulate[0] = 255;     
06297                                         verts[2].modulate[1] = 255;     
06298                                         verts[2].modulate[2] = 255;     
06299                                         verts[2].modulate[3] = 255;
06300 
06301                                         verts[3].st[0] = 1;     
06302                                         verts[3].st[1] = 0;     
06303                                         verts[3].modulate[0] = 255;     
06304                                         verts[3].modulate[1] = 255;     
06305                                         verts[3].modulate[2] = 255;     
06306                                         verts[3].modulate[3] = 255;
06307 
06308                                         //don't capture postrender objects (now we'll postrender the saber so it doesn't get in the capture)
06309                                         trap_R_SetRefractProp(1.0f, 0.0f, qtrue, qtrue);
06310 
06311                                         //shader 2 is always the crazy refractive shader.
06312                                         trap_R_AddPolyToScene( 2, 4, verts );
06313                                 }
06314                                 else
06315         #endif
06316                                 {
06317                                         vec3_t  rgb1={255.0f,255.0f,255.0f};
06318 
06319                                         switch( scolor )
06320                                         {
06321                                                 case SABER_RED:
06322                                                         VectorSet( rgb1, 255.0f, 0.0f, 0.0f );
06323                                                         break;
06324                                                 case SABER_ORANGE:
06325                                                         VectorSet( rgb1, 255.0f, 64.0f, 0.0f );
06326                                                         break;
06327                                                 case SABER_YELLOW:
06328                                                         VectorSet( rgb1, 255.0f, 255.0f, 0.0f );
06329                                                         break;
06330                                                 case SABER_GREEN:
06331                                                         VectorSet( rgb1, 0.0f, 255.0f, 0.0f );
06332                                                         break;
06333                                                 case SABER_BLUE:
06334                                                         VectorSet( rgb1, 0.0f, 64.0f, 255.0f );
06335                                                         break;
06336                                                 case SABER_PURPLE:
06337                                                         VectorSet( rgb1, 220.0f, 0.0f, 255.0f );
06338                                                         break;
06339                                                 default:
06340                                                         VectorSet( rgb1, 0.0f, 64.0f, 255.0f );
06341                                                         break;
06342                                         }
06343 
06344                                         //Here we will use the happy process of filling a struct in with arguments and passing it to a trap function
06345                                         //so that we can take the struct and fill in an actual CTrail type using the data within it once we get it
06346                                         //into the effects area
06347 
06348                                         // Go from new muzzle to new end...then to old end...back down to old muzzle...finally
06349                                         //      connect back to the new muzzle...this is our trail quad
06350                                         VectorCopy( org_, fx.mVerts[0].origin );
06351                                         VectorMA( end, 3.0f, axis_[0], fx.mVerts[1].origin );
06352 
06353                                         VectorCopy( saberTrail->tip, fx.mVerts[2].origin );
06354                                         VectorCopy( saberTrail->base, fx.mVerts[3].origin );
06355 
06356                                         diff = cg.time - saberTrail->lastTime;
06357 
06358                                         // I'm not sure that clipping this is really the best idea
06359                                         //This prevents the trail from showing at all in low framerate situations.
06360                                         //if ( diff <= SABER_TRAIL_TIME * 2 )
06361                                         if ( diff <= 10000 )
06362                                         { //don't draw it if the last time is way out of date
06363                                                 float oldAlpha = 1.0f - ( diff / trailDur );
06364 
06365                                                 if (cg_saberTrail.integer == 2 && cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4)
06366                                                 {//does other stuff below
06367                                                 }
06368                                                 else
06369                                                 {
06370                                                         if ( (!WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum ) && client->saber[saberNum].trailStyle == 1 )
06371                                                                 || ( WP_SaberBladeUseSecondBladeStyle( &client->saber[saberNum], bladeNum ) && client->saber[saberNum].trailStyle2 == 1 ) )
06372                                                         {//motion trail
06373                                                                 fx.mShader = cgs.media.swordTrailShader;
06374                                                                 VectorSet( rgb1, 32.0f, 32.0f, 32.0f ); // make the sith sword trail pretty faint
06375                                                                 trailDur *= 2.0f; // stay around twice as long?
06376                                                         } 
06377                                                         else 
06378                                                         { 
06379                                                                 fx.mShader = cgs.media.saberBlurShader;
06380                                                         }
06381                                                         fx.mKillTime = trailDur;
06382                                                         fx.mSetFlags = FX_USE_ALPHA;
06383                                                 }
06384 
06385                                                 // New muzzle
06386                                                 VectorCopy( rgb1, fx.mVerts[0].rgb );
06387                                                 fx.mVerts[0].alpha = 255.0f;
06388 
06389                                                 fx.mVerts[0].ST[0] = 0.0f;
06390                                                 fx.mVerts[0].ST[1] = 1.0f;
06391                                                 fx.mVerts[0].destST[0] = 1.0f;
06392                                                 fx.mVerts[0].destST[1] = 1.0f;
06393 
06394                                                 // new tip
06395                                                 VectorCopy( rgb1, fx.mVerts[1].rgb );
06396                                                 fx.mVerts[1].alpha = 255.0f;
06397                                                 
06398                                                 fx.mVerts[1].ST[0] = 0.0f;
06399                                                 fx.mVerts[1].ST[1] = 0.0f;
06400                                                 fx.mVerts[1].destST[0] = 1.0f;
06401                                                 fx.mVerts[1].destST[1] = 0.0f;
06402 
06403                                                 // old tip
06404                                                 VectorCopy( rgb1, fx.mVerts[2].rgb );
06405                                                 fx.mVerts[2].alpha = 255.0f;
06406 
06407                                                 fx.mVerts[2].ST[0] = 1.0f - oldAlpha; // NOTE: this just happens to contain the value I want
06408                                                 fx.mVerts[2].ST[1] = 0.0f;
06409                                                 fx.mVerts[2].destST[0] = 1.0f + fx.mVerts[2].ST[0];
06410                                                 fx.mVerts[2].destST[1] = 0.0f;
06411 
06412                                                 // old muzzle
06413                                                 VectorCopy( rgb1, fx.mVerts[3].rgb );
06414                                                 fx.mVerts[3].alpha = 255.0f;
06415 
06416                                                 fx.mVerts[3].ST[0] = 1.0f - oldAlpha; // NOTE: this just happens to contain the value I want
06417                                                 fx.mVerts[3].ST[1] = 1.0f;
06418                                                 fx.mVerts[3].destST[0] = 1.0f + fx.mVerts[2].ST[0];
06419                                                 fx.mVerts[3].destST[1] = 1.0f;
06420 
06421                                                 if (cg_saberTrail.integer == 2 && cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4)
06422                                                 {
06423                                                         trap_R_SetRefractProp(1.0f, 0.0f, qtrue, qtrue); //don't need to do this every frame.. but..
06424 
06425                                                         if (BG_SaberInAttack(cent->currentState.saberMove)
06426                                                                 ||BG_SuperBreakWinAnim(cent->currentState.torsoAnim))
06427                                                         { //in attack, strong trail
06428                                                                 fx.mKillTime = 300;
06429                                                         }
06430                                                         else
06431                                                         { //faded trail
06432                                                                 fx.mKillTime = 40;
06433                                                         }
06434                                                         fx.mShader = 2; //2 is always refractive shader
06435                                                         fx.mSetFlags = FX_USE_ALPHA;
06436                                                 }
06437                                                 /*
06438                                                 else
06439                                                 {
06440                                                         fx.mShader = cgs.media.saberBlurShader;
06441                                                         fx.mKillTime = trailDur;
06442                                                         fx.mSetFlags = FX_USE_ALPHA;
06443                                                 }
06444                                                 */
06445 
06446                                                 trap_FX_AddPrimitive(&fx);
06447                                         }
06448                                 }
06449                         }
06450                 }
06451 
06452                 // we must always do this, even if we aren't active..otherwise we won't know where to pick up from
06453                 VectorCopy( org_, saberTrail->base );
06454                 VectorMA( end, 3.0f, axis_[0], saberTrail->tip );
06455                 saberTrail->lastTime = cg.time;
06456         }
06457 
06458 JustDoIt:
06459 
06460         if (dontDraw)
06461         {
06462                 return;
06463         }
06464 
06465         if ( (client->saber[saberNum].saberFlags2&SFL2_NO_BLADE) )
06466         {//don't actually draw the blade at all
06467                 if ( client->saber[saberNum].numBlades < 3
06468                         && !(client->saber[saberNum].saberFlags2&SFL2_NO_DLIGHT) )
06469                 {//hmm, but still add the dlight
06470                         CG_DoSaberLight( &client->saber[saberNum] );
06471                 }
06472                 return;
06473         }
06474         // Pass in the renderfx flags attached to the saber weapon model...this is done so that saber glows
06475         //      will get rendered properly in a mirror...not sure if this is necessary??
06476         //CG_DoSaber( org_, axis_[0], saberLen, client->saber[saberNum].blade[bladeNum].lengthMax, client->saber[saberNum].blade[bladeNum].radius,
06477         //      scolor, renderfx, (qboolean)(saberNum==0&&bladeNum==0) );
06478         CG_DoSaber( org_, axis_[0], saberLen, client->saber[saberNum].blade[bladeNum].lengthMax, client->saber[saberNum].blade[bladeNum].radius,
06479                 scolor, renderfx, (qboolean)(client->saber[saberNum].numBlades < 3 && !(client->saber[saberNum].saberFlags2&SFL2_NO_DLIGHT)) );
06480 }

markPoly_t* CG_AllocMark  ) 
 

Definition at line 68 of file cg_marks.c.

References cg_activeMarkPolys, CG_FreeMarkPoly(), cg_freeMarkPolys, markPoly_t, memset(), markPoly_s::nextMark, markPoly_s::prevMark, and markPoly_s::time.

Referenced by CG_CreateSaberMarks(), and CG_ImpactMark().

00068                                       {
00069         markPoly_t      *le;
00070         int time;
00071 
00072         if ( !cg_freeMarkPolys ) {
00073                 // no free entities, so free the one at the end of the chain
00074                 // remove the oldest active entity
00075                 time = cg_activeMarkPolys.prevMark->time;
00076                 while (cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time) {
00077                         CG_FreeMarkPoly( cg_activeMarkPolys.prevMark );
00078                 }
00079         }
00080 
00081         le = cg_freeMarkPolys;
00082         cg_freeMarkPolys = cg_freeMarkPolys->nextMark;
00083 
00084         memset( le, 0, sizeof( *le ) );
00085 
00086         // link into the active list
00087         le->nextMark = cg_activeMarkPolys.nextMark;
00088         le->prevMark = &cg_activeMarkPolys;
00089         cg_activeMarkPolys.nextMark->prevMark = le;
00090         cg_activeMarkPolys.nextMark = le;
00091         return le;
00092 }

void CG_CacheG2AnimInfo char *  modelName  ) 
 

Definition at line 6876 of file cg_players.c.

References BG_GetVehicleModelName(), BG_GetVehicleSkinName(), BG_ParseAnimationEvtFile(), BG_ParseAnimationFile(), bgNumAnimEvents, MAX_QPATH, NULL, Q_strrchr(), qfalse, strcpy(), trap_G2API_CleanGhoul2Models(), trap_G2API_GetGLAName(), trap_G2API_InitGhoul2Model(), trap_R_RegisterSkin(), and va().

06877 {
06878         void *g2 = NULL;
06879         char *slash;
06880         char useModel[MAX_QPATH];
06881         char useSkin[MAX_QPATH];
06882         int animIndex;
06883 
06884         strcpy(useModel, modelName);
06885         strcpy(useSkin, modelName);
06886 
06887         if (modelName[0] == '$')
06888         { //it's a vehicle name actually, let's precache the whole vehicle
06889                 BG_GetVehicleModelName(useModel);
06890                 BG_GetVehicleSkinName(useSkin);
06891                 if ( useSkin[0] )
06892                 { //use a custom skin
06893                         trap_R_RegisterSkin(va("models/players/%s/model_%s.skin", useModel, useSkin));
06894                 }
06895                 else
06896                 {
06897                         trap_R_RegisterSkin(va("models/players/%s/model_default.skin", useModel));
06898                 }
06899                 strcpy(useModel, va("models/players/%s/model.glm", useModel));
06900         }
06901 
06902         trap_G2API_InitGhoul2Model(&g2, useModel, 0, 0, 0, 0, 0);
06903 
06904         if (g2)
06905         {
06906                 char GLAName[MAX_QPATH];
06907                 char originalModelName[MAX_QPATH];
06908 
06909                 animIndex = -1;
06910 
06911                 GLAName[0] = 0;
06912                 trap_G2API_GetGLAName(g2, 0, GLAName);
06913 
06914                 strcpy(originalModelName, useModel);
06915                         
06916                 slash = Q_strrchr( GLAName, '/' );
06917                 if ( slash )
06918                 {
06919                         strcpy(slash, "/animation.cfg");
06920 
06921                         animIndex = BG_ParseAnimationFile(GLAName, NULL, qfalse);
06922                 }
06923 
06924                 if (animIndex != -1)
06925                 {
06926                         slash = Q_strrchr( originalModelName, '/' );
06927                         if ( slash )
06928                         {
06929                                 slash++;
06930                                 *slash = 0;
06931                         }
06932 
06933                         BG_ParseAnimationEvtFile(originalModelName, animIndex, bgNumAnimEvents);
06934                 }
06935 
06936                 //Now free the temp instance
06937                 trap_G2API_CleanGhoul2Models(&g2);
06938         }
06939 }

void CG_CheckThirdPersonAlpha centity_t cent,
refEntity_t legs
 

Definition at line 8326 of file cg_players.c.

References vehicleInfo_t::cameraAlpha, cameraCurLoc, vehicleInfo_t::cameraOverride, vehicleInfo_t::cameraRange, centity_t, cg, cg_crosshairPos, CG_G2Trace(), cg_thirdPersonAlpha, playerState_s::clientNum, entityState_s::clientNum, CONTENTS_BODY, centity_s::currentState, trace_t::entityNum, ENTITYNUM_NONE, cg_t::frametime, playerState_s::m_iVehicleNum, centity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, cg_t::predictedPlayerState, refEntity_t::renderfx, cg_t::renderingThirdPerson, RF_FORCE_ENT_ALPHA, refEntity_t::shaderRGBA, vmCvar_t::value, vec3_origin, vec3_t, VectorMA, VectorNormalize(), and VectorSubtract.

Referenced by CG_Player().

08327 {
08328         float alpha = 1.0f;             
08329         int     setFlags = 0;
08330 
08331         if ( cent->m_pVehicle )
08332         {//a vehicle 
08333                 if ( cg.predictedPlayerState.m_iVehicleNum != cent->currentState.clientNum//not mine
08334                         && cent->m_pVehicle->m_pVehicleInfo
08335                         && cent->m_pVehicle->m_pVehicleInfo->cameraOverride
08336                         && cent->m_pVehicle->m_pVehicleInfo->cameraAlpha )//it has alpha
08337                 {//make sure it's not using any alpha
08338                         legs->renderfx |= RF_FORCE_ENT_ALPHA;
08339                         legs->shaderRGBA[3] = 255;
08340                         return;
08341                 }
08342         }
08343 
08344         if ( !cg.renderingThirdPerson )
08345         {
08346                 return;
08347         }
08348 
08349         if ( cg.predictedPlayerState.m_iVehicleNum )
08350         {//in a vehicle
08351                 if ( cg.predictedPlayerState.m_iVehicleNum == cent->currentState.clientNum )
08352                 {//this is my vehicle
08353                         if ( cent->m_pVehicle
08354                                 && cent->m_pVehicle->m_pVehicleInfo
08355                                 && cent->m_pVehicle->m_pVehicleInfo->cameraOverride
08356                                 && cent->m_pVehicle->m_pVehicleInfo->cameraAlpha )
08357                         {//vehicle has auto third-person alpha on
08358                                 trace_t trace;
08359                                 vec3_t  dir2Crosshair, end;
08360                                 VectorSubtract( cg_crosshairPos, cameraCurLoc, dir2Crosshair );
08361                                 VectorNormalize( dir2Crosshair );
08362                                 VectorMA( cameraCurLoc, cent->m_pVehicle->m_pVehicleInfo->cameraRange*2.0f, dir2Crosshair, end );
08363                                 CG_G2Trace( &trace, cameraCurLoc, vec3_origin, vec3_origin, end, ENTITYNUM_NONE, CONTENTS_BODY );
08364                                 if ( trace.entityNum == cent->currentState.clientNum 
08365                                         || trace.entityNum == cg.predictedPlayerState.clientNum)
08366                                 {//hit me or the vehicle I'm in
08367                                         cg_vehThirdPersonAlpha -= 0.1f*cg.frametime/50.0f;
08368                                         if ( cg_vehThirdPersonAlpha < cent->m_pVehicle->m_pVehicleInfo->cameraAlpha )
08369                                         {
08370                                                 cg_vehThirdPersonAlpha = cent->m_pVehicle->m_pVehicleInfo->cameraAlpha;
08371                                         }
08372                                 }
08373                                 else
08374                                 {
08375                                         cg_vehThirdPersonAlpha += 0.1f*cg.frametime/50.0f;
08376                                         if ( cg_vehThirdPersonAlpha > 1.0f )
08377                                         {
08378                                                 cg_vehThirdPersonAlpha = 1.0f;
08379                                         }
08380                                 }
08381                                 alpha = cg_vehThirdPersonAlpha;
08382                         }
08383                         else
08384                         {//use the cvar
08385                                 //reset this
08386                                 cg_vehThirdPersonAlpha = 1.0f;
08387                                 //use the cvar
08388                                 alpha = cg_thirdPersonAlpha.value;
08389                         }
08390                 }
08391         }
08392         else if ( cg.predictedPlayerState.clientNum == cent->currentState.clientNum )
08393         {//it's me
08394                 //reset this
08395                 cg_vehThirdPersonAlpha = 1.0f;
08396                 //use the cvar
08397                 setFlags = RF_FORCE_ENT_ALPHA;
08398                 alpha = cg_thirdPersonAlpha.value;
08399         }
08400         
08401         if ( alpha < 1.0f )
08402         {
08403                 legs->renderfx |= setFlags;
08404                 legs->shaderRGBA[3] = (unsigned char)(alpha * 255.0f);
08405         }
08406 }

void CG_CleanJetpackGhoul2 void   ) 
 

Definition at line 7904 of file cg_players.c.

References cg_g2JetpackInstance, NULL, and trap_G2API_CleanGhoul2Models().

Referenced by CG_DestroyAllGhoul2().

07905 {
07906         if (cg_g2JetpackInstance)
07907         {
07908                 trap_G2API_CleanGhoul2Models(&cg_g2JetpackInstance);
07909                 cg_g2JetpackInstance = NULL;
07910         }
07911 }

void CG_CreateNPCClient clientInfo_t **  ci  ) 
 

Definition at line 7686 of file cg_players.c.

References BG_Alloc().

Referenced by CG_EntityEvent(), CG_Player(), and CG_ResetPlayerEntity().

07687 {
07688         //trap_TrueMalloc((void **)ci, sizeof(clientInfo_t));
07689         *ci = (clientInfo_t *) BG_Alloc(sizeof(clientInfo_t));
07690 }

void CG_CreateSaberMarks vec3_t  start,
vec3_t  end,
vec3_t  normal
 

Definition at line 5462 of file cg_players.c.

References addpolyArgStruct_s::accel, addpolyArgStruct_t, addpolyArgStruct_s::alpha1, addpolyArgStruct_s::alpha2, markPoly_s::alphaFade, addpolyArgStruct_s::alphaParm, addpolyArgStruct_s::bounce, cg, cg_addMarks, CG_AllocMark(), cg_saberDynamicMarks, cg_saberDynamicMarkTime, cgs, markPoly_s::color, DotProduct, addpolyArgStruct_s::ev, addpolyArgStruct_s::flags, vmCvar_t::integer, addpolyArgStruct_s::killTime, markPoly_t, markPoly_s::markShader, MAX_MARK_FRAGMENTS, MAX_MARK_POINTS, MAX_VERTS_ON_POLY, cgs_t::media, memcpy(), memset(), addpolyArgStruct_s::motionDelay, cgMedia_t::mSaberDamageGlow, poly_s::numVerts, addpolyArgStruct_s::numVerts, addpolyArgStruct_s::p, markPoly_s::poly, qfalse, qtrue, random, addpolyArgStruct_s::rgb1, addpolyArgStruct_s::rgb2, addpolyArgStruct_s::rgbParm, cgMedia_t::rivetMarkShader, addpolyArgStruct_s::shader, cg_t::time, markPoly_s::time, trap_CM_MarkFragments(), trap_FX_AddPoly(), vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorScale, VectorSet, VectorSubtract, addpolyArgStruct_s::vel, and markPoly_s::verts.

Referenced by CG_AddSaberBlade().

05463 {
05464 //      byte                    colors[4];
05465         int                             i, j;
05466         int                             numFragments;
05467         vec3_t                  axis[3], originalPoints[4], mid;
05468         vec3_t                  markPoints[MAX_MARK_POINTS], projection;
05469         polyVert_t              *v, verts[MAX_VERTS_ON_POLY];
05470         markPoly_t              *mark;
05471         markFragment_t  markFragments[MAX_MARK_FRAGMENTS], *mf;
05472 
05473         float   radius = 0.65f;
05474 
05475         if ( !cg_addMarks.integer ) 
05476         {
05477                 return;
05478         }
05479 
05480         VectorSubtract( end, start, axis[1] );
05481         VectorNormalize( axis[1] );
05482 
05483         // create the texture axis
05484         VectorCopy( normal, axis[0] );
05485         CrossProduct( axis[1], axis[0], axis[2] );
05486 
05487         // create the full polygon that we'll project
05488         for ( i = 0 ; i < 3 ; i++ ) 
05489         {       // stretch a bit more in the direction that we are traveling in...  debateable as to whether this makes things better or worse
05490                 originalPoints[0][i] = start[i] - radius * axis[1][i] - radius * axis[2][i];
05491                 originalPoints[1][i] = end[i] + radius * axis[1][i] - radius * axis[2][i];
05492                 originalPoints[2][i] = end[i] + radius * axis[1][i] + radius * axis[2][i];
05493                 originalPoints[3][i] = start[i] - radius * axis[1][i] + radius * axis[2][i];
05494         }
05495 
05496         VectorScale( normal, -1, projection );
05497 
05498         // get the fragments
05499         numFragments = trap_CM_MarkFragments( 4, (const float (*)[3])originalPoints,
05500                                         projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments );
05501 
05502         for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) 
05503         {
05504                 // we have an upper limit on the complexity of polygons that we store persistantly
05505                 if ( mf->numPoints > MAX_VERTS_ON_POLY ) 
05506                 {
05507                         mf->numPoints = MAX_VERTS_ON_POLY;
05508                 }
05509 
05510                 for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) 
05511                 {
05512                         vec3_t delta;
05513 
05514                         // Set up our texture coords, this may need some work 
05515                         VectorCopy( markPoints[mf->firstPoint + j], v->xyz );
05516                         VectorAdd( end, start, mid );
05517                         VectorScale( mid, 0.5f, mid );
05518                         VectorSubtract( v->xyz, mid, delta );
05519 
05520                         v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * (0.05f + random() * 0.03f); 
05521                         v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * (0.15f + random() * 0.05f);     
05522                 }
05523 
05524                 if (cg_saberDynamicMarks.integer)
05525                 {
05526                         int i = 0;
05527                         int i_2 = 0;
05528                         addpolyArgStruct_t apArgs;
05529                         vec3_t x;
05530 
05531                         memset (&apArgs, 0, sizeof(apArgs));
05532 
05533                         while (i < 4)
05534                         {
05535                                 while (i_2 < 3)
05536                                 {
05537                                         apArgs.p[i][i_2] = verts[i].xyz[i_2];
05538 
05539                                         i_2++;
05540                                 }
05541 
05542                                 i_2 = 0;
05543                                 i++;
05544                         }
05545 
05546                         i = 0;
05547                         i_2 = 0;
05548 
05549                         while (i < 4)
05550                         {
05551                                 while (i_2 < 2)
05552                                 {
05553                                         apArgs.ev[i][i_2] = verts[i].st[i_2];
05554 
05555                                         i_2++;
05556                                 }
05557 
05558                                 i_2 = 0;
05559                                 i++;
05560                         }
05561 
05562                         //When using addpoly, having a situation like this tends to cause bad results.
05563                         //(I assume it doesn't like trying to draw a polygon over two planes and extends
05564                         //the vertex out to some odd value)
05565                         VectorSubtract(apArgs.p[0], apArgs.p[3], x);
05566                         if (VectorLength(x) > 3.0f)
05567                         {
05568                                 return;
05569                         }
05570 
05571                         apArgs.numVerts = mf->numPoints;
05572                         VectorCopy(vec3_origin, apArgs.vel);
05573                         VectorCopy(vec3_origin, apArgs.accel);
05574 
05575                         apArgs.alpha1 = 1.0f;
05576                         apArgs.alpha2 = 0.0f;
05577                         apArgs.alphaParm = 255.0f;
05578 
05579                         VectorSet(apArgs.rgb1, 0.0f, 0.0f, 0.0f);
05580                         VectorSet(apArgs.rgb2, 0.0f, 0.0f, 0.0f);
05581 
05582                         apArgs.rgbParm = 0.0f;
05583 
05584                         apArgs.bounce = 0;
05585                         apArgs.motionDelay = 0;
05586                         apArgs.killTime = cg_saberDynamicMarkTime.integer;
05587                         apArgs.shader = cgs.media.rivetMarkShader;
05588                         apArgs.flags = 0x08000000|0x00000004;
05589 
05590                         trap_FX_AddPoly(&apArgs);
05591 
05592                         apArgs.shader = cgs.media.mSaberDamageGlow;
05593                         apArgs.rgb1[0] = 215 + random() * 40.0f;
05594                         apArgs.rgb1[1] = 96 + random() * 32.0f;
05595                         apArgs.rgb1[2] = apArgs.alphaParm = random()*15.0f;
05596 
05597                         apArgs.rgb1[0] /= 255;
05598                         apArgs.rgb1[1] /= 255;
05599                         apArgs.rgb1[2] /= 255;
05600                         VectorCopy(apArgs.rgb1, apArgs.rgb2);
05601 
05602                         apArgs.killTime = 100;
05603 
05604                         trap_FX_AddPoly(&apArgs);
05605                 }
05606                 else
05607                 {
05608                         // save it persistantly, do burn first
05609                         mark = CG_AllocMark();
05610                         mark->time = cg.time;
05611                         mark->alphaFade = qtrue;
05612                         mark->markShader = cgs.media.rivetMarkShader;
05613                         mark->poly.numVerts = mf->numPoints;
05614                         mark->color[0] = mark->color[1] = mark->color[2] = mark->color[3] = 255;
05615                         memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
05616 
05617                         // And now do a glow pass
05618                         // by moving the start time back, we can hack it to fade out way before the burn does
05619                         mark = CG_AllocMark();
05620                         mark->time = cg.time - 8500;
05621                         mark->alphaFade = qfalse;
05622                         mark->markShader = cgs.media.mSaberDamageGlow;
05623                         mark->poly.numVerts = mf->numPoints;
05624                         mark->color[0] = 215 + random() * 40.0f;
05625                         mark->color[1] = 96 + random() * 32.0f;
05626                         mark->color[2] = mark->color[3] = random()*15.0f;
05627                         memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
05628                 }
05629         }
05630 }

sfxHandle_t CG_CustomSound int  clientNum,
const char *  soundName
 

Definition at line 170 of file cg_players.c.

References bg_customSiegeSoundNames, cg_buildScript, cg_customCombatSoundNames, cg_customDuelSoundNames, cg_customExtraSoundNames, cg_customJediSoundNames, cg_customSoundNames, cg_entities, cgs, cgs_t::clientinfo, Com_Printf(), COM_StripExtension(), clientInfo_t::combatSounds, clientInfo_t::duelSounds, clientInfo_t::extraSounds, cgs_t::gametype, GT_DUEL, GT_POWERDUEL, GT_TEAM, vmCvar_t::integer, clientInfo_t::jediSounds, MAX_CLIENTS, MAX_CUSTOM_SOUNDS, MAX_QPATH, centity_s::npcClient, sfxHandle_t, clientInfo_t::siegeSounds, clientInfo_t::sounds, strcmp(), and trap_S_RegisterSound().

Referenced by CG_EntityEvent(), CG_PainEvent(), CG_TryPlayCustomSound(), and DoFall().

00170                                                                        {
00171         clientInfo_t *ci;
00172         int                     i;
00173         int                     numCSounds = 0;
00174         int                     numCComSounds = 0;
00175         int                     numCExSounds = 0;
00176         int                     numCJediSounds = 0;
00177         int                     numCSiegeSounds = 0;
00178         int                     numCDuelSounds = 0;
00179         char            lSoundName[MAX_QPATH];
00180 
00181         if ( soundName[0] != '*' ) {
00182                 return trap_S_RegisterSound( soundName );
00183         }
00184 
00185         COM_StripExtension(soundName, lSoundName);
00186 
00187         if ( clientNum < 0 )
00188         {
00189                 clientNum = 0;
00190         }
00191 
00192         if (clientNum >= MAX_CLIENTS)
00193         {
00194                 ci = cg_entities[clientNum].npcClient;
00195         }
00196         else
00197         {
00198                 ci = &cgs.clientinfo[ clientNum ];
00199         }
00200 
00201         if (!ci)
00202         {
00203                 return 0;
00204         }
00205 
00206         for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00207         {
00208                 if (!cg_customSoundNames[i])
00209                 {
00210                         numCSounds = i;
00211                         break;
00212                 }
00213         }
00214 
00215         if (clientNum >= MAX_CLIENTS)
00216         { //these are only for npc's
00217                 for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00218                 {
00219                         if (!cg_customCombatSoundNames[i])
00220                         {
00221                                 numCComSounds = i;
00222                                 break;
00223                         }
00224                 }
00225 
00226                 for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00227                 {
00228                         if (!cg_customExtraSoundNames[i])
00229                         {
00230                                 numCExSounds = i;
00231                                 break;
00232                         }
00233                 }
00234 
00235                 for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00236                 {
00237                         if (!cg_customJediSoundNames[i])
00238                         {
00239                                 numCJediSounds = i;
00240                                 break;
00241                         }
00242                 }
00243         }
00244 
00245     if (cgs.gametype >= GT_TEAM || cg_buildScript.integer)
00246         { //siege only
00247                 for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00248                 {
00249                         if (!bg_customSiegeSoundNames[i])
00250                         {
00251                                 numCSiegeSounds = i;
00252                                 break;
00253                         }
00254                 }
00255         }
00256 
00257     if (cgs.gametype == GT_DUEL
00258                 || cgs.gametype == GT_POWERDUEL
00259                 || cg_buildScript.integer)
00260         { //Duel only
00261                 for (i = 0; i < MAX_CUSTOM_SOUNDS; i++)
00262                 {
00263                         if (!cg_customDuelSoundNames[i])
00264                         {
00265                                 numCDuelSounds = i;
00266                                 break;
00267                         }
00268                 }
00269         }
00270 
00271         for ( i = 0 ; i < MAX_CUSTOM_SOUNDS ; i++ )
00272         {
00273                 if ( i < numCSounds && !strcmp( lSoundName, cg_customSoundNames[i] ) )
00274                 {
00275                         return ci->sounds[i];
00276                 }
00277                 else if ( (cgs.gametype >= GT_TEAM || cg_buildScript.integer) && i < numCSiegeSounds && !strcmp( lSoundName, bg_customSiegeSoundNames[i] ) )
00278                 { //siege only
00279                         return ci->siegeSounds[i];
00280                 }
00281                 else if ( (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL || cg_buildScript.integer) && i < numCDuelSounds && !strcmp( lSoundName, cg_customDuelSoundNames[i] ) )
00282                 { //siege only
00283                         return ci->duelSounds[i];
00284                 }
00285                 else if ( clientNum >= MAX_CLIENTS && i < numCComSounds && !strcmp( lSoundName, cg_customCombatSoundNames[i] ) )
00286                 { //npc only
00287                         return ci->combatSounds[i];
00288                 }
00289                 else if ( clientNum >= MAX_CLIENTS && i < numCExSounds && !strcmp( lSoundName, cg_customExtraSoundNames[i] ) )
00290                 { //npc only
00291                         return ci->extraSounds[i];
00292                 }
00293                 else if ( clientNum >= MAX_CLIENTS && i < numCJediSounds && !strcmp( lSoundName, cg_customJediSoundNames[i] ) )
00294                 { //npc only
00295                         return ci->jediSounds[i];
00296                 }
00297         }
00298 
00299         //CG_Error( "Unknown custom sound: %s", lSoundName );
00300 #ifndef FINAL_BUILD
00301         Com_Printf( "Unknown custom sound: %s", lSoundName );
00302 #endif
00303         return 0;
00304 }

void CG_DestroyNPCClient clientInfo_t **  ci  ) 
 

Definition at line 7692 of file cg_players.c.

References memset().

07693 {
07694         memset(*ci, 0, sizeof(clientInfo_t));
07695         //trap_TrueFree((void **)ci);
07696 }

void CG_Disintegration centity_t cent,
refEntity_t ent
 

Definition at line 653 of file cg_ents.c.

References AngleVectors(), centity_t, cg, cg_timescale, cgs, crandom, centity_s::currentState, refEntity_t::customShader, cgMedia_t::disruptorShader, centity_s::dustTrailTime, cgs_t::effects, refEntity_t::endTime, cgs_t::gameModels, centity_s::ghoul2, centity_s::lerpAngles, centity_s::lerpOrigin, cgEffects_t::mDisruptorDeathSmoke, cgs_t::media, centity_s::modelScale, NULL, refEntity_t::oldorigin, ORIGIN, refEntity_t::origin, entityState_s::origin2, random, cg_t::refdef, refEntity_t::renderfx, RF_DISINTEGRATE1, RF_DISINTEGRATE2, cg_t::time, trap_FX_PlayEffectID(), trap_G2API_AddBolt(), trap_G2API_GetBoltMatrix(), trap_R_AddRefEntityToScene(), vmCvar_t::value, vec3_t, vectoangles(), VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSet, VectorSubtract, refdef_t::viewaxis, and YAW.

Referenced by CG_Player().

00654 {
00655         vec3_t tempAng, hitLoc;
00656         float tempLength;
00657 
00658         VectorCopy(cent->currentState.origin2, hitLoc);
00659 
00660         VectorSubtract( hitLoc, ent->origin, ent->oldorigin );
00661         
00662         tempLength = VectorNormalize( ent->oldorigin );
00663         vectoangles( ent->oldorigin, tempAng );
00664         tempAng[YAW] -= cent->lerpAngles[YAW];
00665         AngleVectors( tempAng, ent->oldorigin, NULL, NULL );
00666         VectorScale( ent->oldorigin, tempLength, ent->oldorigin );
00667 
00668         ent->endTime = cent->dustTrailTime;
00669 
00670         ent->renderfx |= RF_DISINTEGRATE2;
00671         ent->customShader = cgs.media.disruptorShader;
00672         trap_R_AddRefEntityToScene( ent );
00673 
00674         ent->renderfx &= ~(RF_DISINTEGRATE2);
00675         ent->renderfx |= (RF_DISINTEGRATE1);
00676         ent->customShader = 0;
00677         trap_R_AddRefEntityToScene( ent );
00678 
00679         if ( cg.time - ent->endTime < 1000 && (cg_timescale.value * cg_timescale.value * random()) > 0.05f )
00680         {
00681                 vec3_t fxOrg, fxDir;
00682                 mdxaBone_t      boltMatrix;
00683                 int torsoBolt = trap_G2API_AddBolt(cent->ghoul2, 0, "lower_lumbar");
00684 
00685                 VectorSet(fxDir, 0, 1, 0);
00686 
00687                 trap_G2API_GetBoltMatrix( cent->ghoul2, 0, torsoBolt, &boltMatrix, cent->lerpAngles, cent->lerpOrigin, cg.time, 
00688                                 cgs.gameModels, cent->modelScale);
00689                                 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, fxOrg );
00690 
00691                 VectorMA( fxOrg, -18, cg.refdef.viewaxis[0], fxOrg );
00692                 fxOrg[2] += crandom() * 20;
00693                 trap_FX_PlayEffectID( cgs.effects.mDisruptorDeathSmoke, fxOrg, fxDir, -1, -1 );
00694 
00695                 if ( random() > 0.5f )
00696                 {
00697                         trap_FX_PlayEffectID( cgs.effects.mDisruptorDeathSmoke, fxOrg, fxDir, -1, -1 );
00698                 }
00699         }
00700 }

void CG_DoSaber vec3_t  origin,
vec3_t  dir,
float  length,
float  lengthMax,
float  radius,
saber_colors_t  color,
int  rfx,
qboolean  doLight
 

Definition at line 5320 of file cg_players.c.

References refEntity_t::axis, cgMedia_t::blueSaberCoreShader, cgMedia_t::blueSaberGlowShader, cg_saberTrail, cg_shadows, cgs, crandom, refEntity_t::customShader, cgs_t::glconfig, cgMedia_t::greenSaberCoreShader, cgMedia_t::greenSaberGlowShader, vmCvar_t::integer, cgs_t::media, memset(), refEntity_t::oldorigin, cgMedia_t::orangeSaberCoreShader, cgMedia_t::orangeSaberGlowShader, refEntity_t::origin, cgMedia_t::purpleSaberCoreShader, cgMedia_t::purpleSaberGlowShader, qhandle_t, refEntity_t::radius, random, cgMedia_t::redSaberCoreShader, cgMedia_t::redSaberGlowShader, refEntity_t::renderfx, refEntity_t::reType, RF_FORCEPOST, RT_LINE, RT_SABER_GLOW, SABER_BLUE, saber_colors_t, SABER_GREEN, SABER_ORANGE, SABER_PURPLE, SABER_RED, SABER_YELLOW, refEntity_t::saberLength, refEntity_t::shaderRGBA, refEntity_t::shaderTexCoord, glconfig_t::stencilBits, trap_R_AddLightToScene(), trap_R_AddRefEntityToScene(), vec3_t, VectorCopy, VectorMA, cgMedia_t::yellowSaberCoreShader, and cgMedia_t::yellowSaberGlowShader.

Referenced by CG_AddSaberBlade().

05321 {
05322         vec3_t          mid;
05323         qhandle_t       blade = 0, glow = 0;
05324         refEntity_t saber;
05325         float radiusmult;
05326         float radiusRange;
05327         float radiusStart;
05328 
05329         if ( length < 0.5f )
05330         {
05331                 // if the thing is so short, just forget even adding me.
05332                 return;
05333         }
05334 
05335         // Find the midpoint of the saber for lighting purposes
05336         VectorMA( origin, length * 0.5f, dir, mid );
05337 
05338         switch( color )
05339         {
05340                 case SABER_RED:
05341                         glow = cgs.media.redSaberGlowShader;
05342                         blade = cgs.media.redSaberCoreShader;
05343                         break;
05344                 case SABER_ORANGE:
05345                         glow = cgs.media.orangeSaberGlowShader;
05346                         blade = cgs.media.orangeSaberCoreShader;
05347                         break;
05348                 case SABER_YELLOW:
05349                         glow = cgs.media.yellowSaberGlowShader;
05350                         blade = cgs.media.yellowSaberCoreShader;
05351                         break;
05352                 case SABER_GREEN:
05353                         glow = cgs.media.greenSaberGlowShader;
05354                         blade = cgs.media.greenSaberCoreShader;
05355                         break;
05356                 case SABER_BLUE:
05357                         glow = cgs.media.blueSaberGlowShader;
05358                         blade = cgs.media.blueSaberCoreShader;
05359                         break;
05360                 case SABER_PURPLE:
05361                         glow = cgs.media.purpleSaberGlowShader;
05362                         blade = cgs.media.purpleSaberCoreShader;
05363                         break;
05364                 default:
05365                         glow = cgs.media.blueSaberGlowShader;
05366                         blade = cgs.media.blueSaberCoreShader;
05367                         break;
05368         }
05369 
05370         if (doLight)
05371         {       // always add a light because sabers cast a nice glow before they slice you in half!!  or something...
05372                 vec3_t rgb={1,1,1};
05373                 CG_RGBForSaberColor( color, rgb );
05374                 trap_R_AddLightToScene( mid, (length*1.4f) + (random()*3.0f), rgb[0], rgb[1], rgb[2] );
05375         }
05376 
05377         memset( &saber, 0, sizeof( refEntity_t ));
05378 
05379         // Saber glow is it's own ref type because it uses a ton of sprites, otherwise it would eat up too many
05380         //      refEnts to do each glow blob individually
05381         saber.saberLength = length;
05382 
05383         // Jeff, I did this because I foolishly wished to have a bright halo as the saber is unleashed.  
05384         // It's not quite what I'd hoped tho.  If you have any ideas, go for it!  --Pat
05385         if (length < lengthMax)
05386         {
05387                 radiusmult = 1.0 + (2.0 / length);              // Note this creates a curve, and length cannot be < 0.5.
05388         }
05389         else
05390         {
05391                 radiusmult = 1.0;
05392         }
05393 
05394         if (cg_saberTrail.integer == 2 && cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4)
05395         { //draw the blade as a post-render so it doesn't get in the cap...
05396                 rfx |= RF_FORCEPOST;
05397         }
05398 
05399         radiusRange = radius * 0.075f;
05400         radiusStart = radius-radiusRange;
05401 
05402         saber.radius = (radiusStart + crandom() * radiusRange)*radiusmult;
05403         //saber.radius = (2.8f + crandom() * 0.2f)*radiusmult;
05404 
05405         VectorCopy( origin, saber.origin );
05406         VectorCopy( dir, saber.axis[0] );
05407         saber.reType = RT_SABER_GLOW;
05408         saber.customShader = glow;
05409         saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
05410         saber.renderfx = rfx;
05411 
05412         trap_R_AddRefEntityToScene( &saber );
05413 
05414         // Do the hot core
05415         VectorMA( origin, length, dir, saber.origin );
05416         VectorMA( origin, -1, dir, saber.oldorigin );
05417 
05418 
05419 //      CG_TestLine(saber.origin, saber.oldorigin, 50, 0x000000ff, 3);
05420         saber.customShader = blade;
05421         saber.reType = RT_LINE;
05422         radiusStart = radius/3.0f;
05423         saber.radius = (radiusStart + crandom() * radiusRange)*radiusmult;
05424 //      saber.radius = (1.0 + crandom() * 0.2f)*radiusmult;
05425 
05426         saber.shaderTexCoord[0] = saber.shaderTexCoord[1] = 1.0f;
05427         saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
05428 
05429         trap_R_AddRefEntityToScene( &saber );
05430 }

void CG_DrawPlayerShield centity_t cent,
vec3_t  origin
 

Definition at line 5107 of file cg_players.c.

References AnglesToAxis(), refEntity_t::axis, centity_t, cg, cgs, centity_s::currentState, refEntity_t::customShader, centity_s::damageAngles, centity_s::damageTime, EF_DEAD, entityState_s::eFlags, cgMedia_t::halfShieldModel, cgMedia_t::halfShieldShader, refEntity_t::hModel, cgs_t::media, memset(), MIN_SHIELD_TIME, refEntity_t::origin, random, refEntity_t::shaderRGBA, cg_t::time, trap_R_AddRefEntityToScene(), vec3_t, VectorCopy, and VectorScale.

Referenced by CG_PlayerHitFX().

05108 {
05109         refEntity_t ent;
05110         int                     alpha;
05111         float           scale;
05112         
05113         // Don't draw the shield when the player is dead.
05114         if (cent->currentState.eFlags & EF_DEAD)
05115         {
05116                 return;
05117         }
05118 
05119         memset( &ent, 0, sizeof( ent ) );
05120 
05121         VectorCopy( origin, ent.origin );
05122         ent.origin[2] += 10.0;
05123         AnglesToAxis( cent->damageAngles, ent.axis );
05124 
05125         alpha = 255.0 * ((cent->damageTime - cg.time) / MIN_SHIELD_TIME) + random()*16;
05126         if (alpha>255)
05127                 alpha=255;
05128 
05129         // Make it bigger, but tighter if more solid
05130         scale = 1.4 - ((float)alpha*(0.4/255.0));               // Range from 1.0 to 1.4
05131         VectorScale( ent.axis[0], scale, ent.axis[0] );
05132         VectorScale( ent.axis[1], scale, ent.axis[1] );
05133         VectorScale( ent.axis[2], scale, ent.axis[2] );
05134 
05135         ent.hModel = cgs.media.halfShieldModel;
05136         ent.customShader = cgs.media.halfShieldShader;
05137         ent.shaderRGBA[0] = alpha;
05138         ent.shaderRGBA[1] = alpha;
05139         ent.shaderRGBA[2] = alpha;
05140         ent.shaderRGBA[3] = 255;
05141         trap_R_AddRefEntityToScene( &ent );
05142 }

void CG_DrawPlayerSphere centity_t cent,
vec3_t  origin,
float  scale,
int  shader
 

Definition at line 6522 of file cg_players.c.

References AnglesToAxis(), refEntity_t::axis, centity_t, cg, cg_renderToTextureFX, cgs, playerState_s::clientNum, centity_s::currentState, refEntity_t::customShader, EF_DEAD, entityState_s::eFlags, cgMedia_t::endarkenmentShader, cgMedia_t::enlightenmentShader, cgMedia_t::halfShieldModel, refEntity_t::hModel, vmCvar_t::integer, cgMedia_t::invulnerabilityShader, cgs_t::media, memset(), refEntity_t::nonNormalizedAxes, entityState_s::number, refEntity_t::origin, PITCH, cg_t::predictedPlayerState, qtrue, refEntity_t::radius, cg_t::refdef, refEntity_t::renderfx, cg_t::renderingThirdPerson, RF_DISTORTION, RF_FORCE_ENT_ALPHA, ROLL, refEntity_t::shaderRGBA, trap_R_AddRefEntityToScene(), trap_R_RegisterShader(), vec3_t, vectoangles(), VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSubtract, refdef_t::vieworg, and cgMedia_t::ysalimariShader.

Referenced by CG_Player().

06523 {
06524         refEntity_t ent;
06525         vec3_t ang;
06526         float vLen;
06527         vec3_t viewDir;
06528         
06529         // Don't draw the shield when the player is dead.
06530         if (cent->currentState.eFlags & EF_DEAD)
06531         {
06532                 return;
06533         }
06534 
06535         memset( &ent, 0, sizeof( ent ) );
06536 
06537         VectorCopy( origin, ent.origin );
06538         ent.origin[2] += 9.0;
06539 
06540         VectorSubtract(ent.origin, cg.refdef.vieworg, ent.axis[0]);
06541         vLen = VectorLength(ent.axis[0]);
06542         if (vLen <= 0.1f)
06543         {       // Entity is right on vieworg.  quit.
06544                 return;
06545         }
06546 
06547         VectorCopy(ent.axis[0], viewDir);
06548         VectorInverse(viewDir);
06549         VectorNormalize(viewDir);
06550 
06551         vectoangles(ent.axis[0], ang);
06552         ang[ROLL] += 180.0f;
06553         ang[PITCH] += 180.0f;
06554         AnglesToAxis(ang, ent.axis);
06555 
06556         VectorScale(ent.axis[0], scale, ent.axis[0]);
06557         VectorScale(ent.axis[1], scale, ent.axis[1]);
06558         VectorScale(ent.axis[2], scale, ent.axis[2]);
06559 
06560         ent.nonNormalizedAxes = qtrue;
06561 
06562         ent.hModel = cgs.media.halfShieldModel;
06563         ent.customShader = shader;      
06564 
06565         trap_R_AddRefEntityToScene( &ent );
06566 
06567         if (!cg.renderingThirdPerson && cent->currentState.number == cg.predictedPlayerState.clientNum)
06568         { //don't do the rest then
06569                 return;
06570         }
06571         if (!cg_renderToTextureFX.integer)
06572         {
06573                 return;
06574         }
06575 
06576         ang[PITCH] -= 180.0f;
06577         AnglesToAxis(ang, ent.axis);
06578 
06579         VectorScale(ent.axis[0], scale*0.5f, ent.axis[0]);
06580         VectorScale(ent.axis[1], scale*0.5f, ent.axis[1]);
06581         VectorScale(ent.axis[2], scale*0.5f, ent.axis[2]);
06582 
06583         ent.renderfx = (RF_DISTORTION|RF_FORCE_ENT_ALPHA);
06584         if (shader == cgs.media.invulnerabilityShader)
06585         { //ok, ok, this is a little hacky. sorry!
06586                 ent.shaderRGBA[0] = 0;
06587                 ent.shaderRGBA[1] = 255;
06588                 ent.shaderRGBA[2] = 0;
06589                 ent.shaderRGBA[3] = 100;
06590         }
06591         else if (shader == cgs.media.ysalimariShader)
06592         {
06593                 ent.shaderRGBA[0] = 255;
06594                 ent.shaderRGBA[1] = 255;
06595                 ent.shaderRGBA[2] = 0;
06596                 ent.shaderRGBA[3] = 100;
06597         }
06598         else if (shader == cgs.media.endarkenmentShader)
06599         {
06600                 ent.shaderRGBA[0] = 100;
06601                 ent.shaderRGBA[1] = 0;
06602                 ent.shaderRGBA[2] = 0;
06603                 ent.shaderRGBA[3] = 20;
06604         }
06605         else if (shader == cgs.media.enlightenmentShader)
06606         {
06607                 ent.shaderRGBA[0] = 255;
06608                 ent.shaderRGBA[1] = 255;
06609                 ent.shaderRGBA[2] = 255;
06610                 ent.shaderRGBA[3] = 20;
06611         }
06612         else
06613         { //ysal red/blue, boon
06614                 ent.shaderRGBA[0] = 255.0f;
06615                 ent.shaderRGBA[1] = 255.0f;
06616                 ent.shaderRGBA[2] = 255.0f;
06617                 ent.shaderRGBA[3] = 20;
06618         }
06619 
06620         ent.radius = 256;
06621 
06622         VectorMA(ent.origin, 40.0f, viewDir, ent.origin);
06623 
06624         ent.customShader = trap_R_RegisterShader("effects/refract_2");
06625         trap_R_AddRefEntityToScene( &ent );
06626 }

void CG_G2Animated centity_t cent  ) 
 

Definition at line 7454 of file cg_players.c.

References BG_NUM_TOGGLEABLE_SURFACES, bgToggleableSurfaceDebris, bgToggleableSurfaces, centity_t, CG_G2AnimEntModelLoad(), CG_Player(), CG_RagDoll(), CG_ReattachLimb(), cgs, centity_s::currentState, EF_DEAD, EF_RAG, cgs_t::effects, entityState_s::eFlags, centity_s::ghoul2, centity_s::lerpAngles, centity_s::localAnimIndex, cgEffects_t::mShipDestDestroyed, centity_s::npcLocalSurfOff, centity_s::npcLocalSurfOn, qtrue, centity_s::smoothYaw, entityState_s::surfacesOff, entityState_s::surfacesOn, centity_s::torsoBolt, trap_G2API_SetSurfaceOnOff(), TURN_OFF, TURN_ON, vec3_t, VectorClear, and YAW.

07455 {
07456 #ifdef SMOOTH_G2ANIM_LERPANGLES
07457         float angSmoothFactor = 0.7f;
07458 #endif
07459 
07460 
07461         if (!cent->ghoul2)
07462         { //Initialize this g2 anim ent, then return (will start rendering next frame)
07463                 CG_G2AnimEntModelLoad(cent);
07464                 cent->npcLocalSurfOff = 0;
07465                 cent->npcLocalSurfOn = 0;
07466                 return;
07467         }
07468 
07469         if (cent->npcLocalSurfOff != cent->currentState.surfacesOff ||
07470                 cent->npcLocalSurfOn != cent->currentState.surfacesOn)
07471         { //looks like it's time for an update.
07472                 int i = 0;
07473 
07474                 while (i < BG_NUM_TOGGLEABLE_SURFACES && bgToggleableSurfaces[i])
07475                 {
07476                         if (!(cent->npcLocalSurfOff & (1 << i)) &&
07477                                 (cent->currentState.surfacesOff & (1 << i)))
07478                         { //it wasn't off before but it's off now, so reflect this change in the g2 instance.
07479                                 if (bgToggleableSurfaceDebris[i] > 0)
07480                                 { //make some local debris of this thing?
07481                                         //FIXME: throw off the proper model effect, too
07482                                         CG_CreateSurfaceDebris(cent, i, cgs.effects.mShipDestDestroyed, qtrue);
07483                                 }
07484 
07485                                 trap_G2API_SetSurfaceOnOff(cent->ghoul2, bgToggleableSurfaces[i], TURN_OFF);
07486                         }
07487 
07488                         if (!(cent->npcLocalSurfOn & (1 << i)) &&
07489                                 (cent->currentState.surfacesOn & (1 << i)))
07490                         { //same as above, but on instead of off.
07491                                 trap_G2API_SetSurfaceOnOff(cent->ghoul2, bgToggleableSurfaces[i], TURN_ON);
07492                         }
07493 
07494                         i++;
07495                 }
07496 
07497                 cent->npcLocalSurfOff = cent->currentState.surfacesOff;
07498                 cent->npcLocalSurfOn = cent->currentState.surfacesOn;
07499         }
07500 
07501 
07502         /*
07503         if (cent->currentState.weapon &&
07504                 !trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1) &&
07505                 !(cent->currentState.eFlags & EF_DEAD))
07506         { //if the server says we have a weapon and we haven't copied one onto ourselves yet, then do so.
07507                 trap_G2API_CopySpecificGhoul2Model(g2WeaponInstances[cent->currentState.weapon], 0, cent->ghoul2, 1);
07508 
07509                 if (cent->currentState.weapon == WP_SABER)
07510                 {
07511                         trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( "sound/weapons/saber/saberon.wav" ));
07512                 }
07513         }
07514         */
07515 
07516         if (cent->torsoBolt && !(cent->currentState.eFlags & EF_DEAD))
07517         { //he's alive and has a limb missing still, reattach it and reset the weapon
07518                 CG_ReattachLimb(cent);
07519         }
07520 
07521         if (((cent->currentState.eFlags & EF_DEAD) || (cent->currentState.eFlags & EF_RAG)) && !cent->localAnimIndex)
07522         {
07523                 vec3_t forcedAngles;
07524 
07525                 VectorClear(forcedAngles);
07526                 forcedAngles[YAW] = cent->lerpAngles[YAW];
07527 
07528                 CG_RagDoll(cent, forcedAngles);
07529         }
07530 
07531 #ifdef SMOOTH_G2ANIM_LERPANGLES
07532         if ((cent->lerpAngles[YAW] > 0 && cent->smoothYaw < 0) ||
07533                 (cent->lerpAngles[YAW] < 0 && cent->smoothYaw > 0))
07534         { //keep it from snapping around on the threshold
07535                 cent->smoothYaw = -cent->smoothYaw;
07536         }
07537         cent->lerpAngles[YAW] = cent->smoothYaw+(cent->lerpAngles[YAW]-cent->smoothYaw)*angSmoothFactor;
07538         cent->smoothYaw = cent->lerpAngles[YAW];
07539 #endif
07540 
07541         //now just render as a player
07542         CG_Player(cent);
07543 
07544         /*
07545         if ( cg_showVehBounds.integer )
07546         {//show vehicle bboxes
07547                 if ( cent->currentState.clientNum >= MAX_CLIENTS
07548                         && cent->currentState.NPC_class == CLASS_VEHICLE 
07549                         && cent->m_pVehicle
07550                         && cent->m_pVehicle->m_pVehicleInfo 
07551                         && cent->currentState.clientNum != cg.predictedVehicleState.clientNum )
07552                 {//not the predicted vehicle
07553                         vec3_t NPCDEBUG_RED = {1.0, 0.0, 0.0};
07554                         vec3_t absmin, absmax;
07555                         vec3_t bmins, bmaxs;
07556                         float *old = cent->m_pVehicle->m_vOrientation;
07557                         cent->m_pVehicle->m_vOrientation = &cent->lerpAngles[0];
07558 
07559                         BG_VehicleAdjustBBoxForOrientation( cent->m_pVehicle, cent->lerpOrigin, bmins, bmaxs,
07560                                                                                 cent->currentState.number, MASK_PLAYERSOLID, NULL );
07561                         cent->m_pVehicle->m_vOrientation = old;
07562 
07563                         VectorAdd( cent->lerpOrigin, bmins, absmin );
07564                         VectorAdd( cent->lerpOrigin, bmaxs, absmax );
07565                         CG_Cube( absmin, absmax, NPCDEBUG_RED, 0.25 );
07566                 }
07567         }
07568         */
07569 }

void CG_G2AnimEntModelLoad centity_t cent  ) 
 

Definition at line 6998 of file cg_players.c.

References BG_GetVehicleModelName(), BG_ParseAnimationEvtFile(), BG_ParseAnimationFile(), BG_VehicleGetIndex(), bgEntity_t, bgNumAnimEvents, centity_t, CG_ConfigString(), CG_HandleAppendedSkin(), CG_HandleNPCSounds(), cgs, cgSendPS, CLASS_VEHICLE, Com_sprintf(), CS_MODELS, centity_s::currentState, centity_s::eventAnimIndex, G_CreateAnimalNPC(), G_CreateFighterNPC(), G_CreateSpeederNPC(), G_CreateWalkerNPC(), g_vehicleInfo, centity_s::ghoul2, clientInfo_t::ghoul2Weapons, turretStats_t::gunnerViewTag, centity_s::localAnimIndex, Vehicle_s::m_iDroidUnitTag, Vehicle_s::m_iExhaustTag, Vehicle_s::m_iGunnerViewTag, Vehicle_s::m_iMuzzleTag, Vehicle_s::m_pParentEntity, centity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_vOrientation, MAX_QPATH, MAX_SABERS, MAX_VEHICLE_EXHAUSTS, MAX_VEHICLE_MUZZLES, MAX_VEHICLE_TURRETS, cgs_t::media, saberInfo_t::model, entityState_s::modelindex, cgMedia_t::noAmmoSound, centity_s::noFace, centity_s::noLumbar, entityState_s::NPC_class, centity_s::npcClient, entityState_s::npcSaber1, entityState_s::npcSaber2, NULL, entityState_s::number, Q_strrchr(), qfalse, qtrue, clientInfo_t::saber, vehicleInfo_t::skin, strcpy(), strstr(), trap_G2API_AddBolt(), trap_G2API_CleanGhoul2Models(), trap_G2API_GetGLAName(), trap_G2API_InitGhoul2Model(), trap_G2API_SetSkin(), trap_R_RegisterSkin(), trap_S_RegisterSound(), trap_S_ShutUp(), vehicleInfo_t::turret, vehicleInfo_t::type, va(), VH_ANIMAL, VH_FIGHTER, VH_SPEEDER, VH_WALKER, and WP_SetSaber().

Referenced by CG_G2Animated().

06999 {
07000         const char *cModelName = CG_ConfigString( CS_MODELS+cent->currentState.modelindex );
07001 
07002         if (!cent->npcClient)
07003         { //have not init'd client yet
07004                 return;
07005         }
07006 
07007         if (cModelName && cModelName[0])
07008         {
07009                 char modelName[MAX_QPATH];
07010                 int skinID;
07011                 char *slash;
07012 
07013                 strcpy(modelName, cModelName);
07014 
07015                 if (cent->currentState.NPC_class == CLASS_VEHICLE && modelName[0] == '$')
07016                 { //vehicles pass their veh names over as model names, then we get the model name from the veh type
07017                         //create a vehicle object clientside for this type
07018                         char *vehType = &modelName[1];
07019                         int iVehIndex = BG_VehicleGetIndex( vehType );
07020                         
07021                         switch( g_vehicleInfo[iVehIndex].type )
07022                         {
07023                                 case VH_ANIMAL:
07024                                         // Create the animal (making sure all it's data is initialized).
07025                                         G_CreateAnimalNPC( &cent->m_pVehicle, vehType );
07026                                         break;
07027                                 case VH_SPEEDER:
07028                                         // Create the speeder (making sure all it's data is initialized).
07029                                         G_CreateSpeederNPC( &cent->m_pVehicle, vehType );
07030                                         break;
07031                                 case VH_FIGHTER:
07032                                         // Create the fighter (making sure all it's data is initialized).
07033                                         G_CreateFighterNPC( &cent->m_pVehicle, vehType );
07034                                         break;
07035                                 case VH_WALKER:
07036                                         // Create the walker (making sure all it's data is initialized).
07037                                         G_CreateWalkerNPC( &cent->m_pVehicle, vehType );
07038                                         break;
07039 
07040                                 default:
07041                                         assert(!"vehicle with an unknown type - couldn't create vehicle_t");
07042                                         break;
07043                         }
07044                         
07045                         //set up my happy prediction hack
07046                         cent->m_pVehicle->m_vOrientation = &cgSendPS[cent->currentState.number]->vehOrientation[0];
07047 
07048                         cent->m_pVehicle->m_pParentEntity = (bgEntity_t *)cent;
07049 
07050                         //attach the handles for fx cgame-side
07051                         CG_RegisterVehicleAssets(cent->m_pVehicle);
07052 
07053                         BG_GetVehicleModelName(modelName);
07054                         if (cent->m_pVehicle->m_pVehicleInfo->skin &&
07055                                 cent->m_pVehicle->m_pVehicleInfo->skin[0])
07056                         { //use a custom skin
07057                                 skinID = trap_R_RegisterSkin(va("models/players/%s/model_%s.skin", modelName, cent->m_pVehicle->m_pVehicleInfo->skin));
07058                         }
07059                         else
07060                         {
07061                                 skinID = trap_R_RegisterSkin(va("models/players/%s/model_default.skin", modelName));
07062                         }
07063                         strcpy(modelName, va("models/players/%s/model.glm", modelName));
07064 
07065                         //this sound is *only* used for vehicles now
07066                         cgs.media.noAmmoSound = trap_S_RegisterSound( "sound/weapons/noammo.wav" );
07067                 }
07068                 else
07069                 {
07070                         skinID = CG_HandleAppendedSkin(modelName); //get the skin if there is one.
07071                 }
07072 
07073                 if (cent->ghoul2)
07074                 { //clean it first!
07075             trap_G2API_CleanGhoul2Models(&cent->ghoul2);
07076                 }
07077 
07078                 trap_G2API_InitGhoul2Model(&cent->ghoul2, modelName, 0, skinID, 0, 0, 0);
07079 
07080                 if (cent->ghoul2)
07081                 {
07082                         char GLAName[MAX_QPATH];
07083                         char originalModelName[MAX_QPATH];
07084                         char *saber;
07085                         int j = 0;
07086 
07087                         if (cent->currentState.NPC_class == CLASS_VEHICLE &&
07088                                 cent->m_pVehicle)
07089                         { //do special vehicle stuff
07090                                 char strTemp[128];
07091                                 int i;
07092 
07093                                 // Setup the default first bolt
07094                                 i = trap_G2API_AddBolt( cent->ghoul2, 0, "model_root" );
07095 
07096                                 // Setup the droid unit.
07097                                 cent->m_pVehicle->m_iDroidUnitTag = trap_G2API_AddBolt( cent->ghoul2, 0, "*droidunit" );
07098 
07099                                 // Setup the Exhausts.
07100                                 for ( i = 0; i < MAX_VEHICLE_EXHAUSTS; i++ )
07101                                 {
07102                                         Com_sprintf( strTemp, 128, "*exhaust%i", i + 1 );
07103                                         cent->m_pVehicle->m_iExhaustTag[i] = trap_G2API_AddBolt( cent->ghoul2, 0, strTemp );
07104                                 }
07105 
07106                                 // Setup the Muzzles.
07107                                 for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
07108                                 {
07109                                         Com_sprintf( strTemp, 128, "*muzzle%i", i + 1 );
07110                                         cent->m_pVehicle->m_iMuzzleTag[i] = trap_G2API_AddBolt( cent->ghoul2, 0, strTemp );
07111                                         if ( cent->m_pVehicle->m_iMuzzleTag[i] == -1 )
07112                                         {//ergh, try *flash?
07113                                                 Com_sprintf( strTemp, 128, "*flash%i", i + 1 );
07114                                                 cent->m_pVehicle->m_iMuzzleTag[i] = trap_G2API_AddBolt( cent->ghoul2, 0, strTemp );
07115                                         }
07116                                 }
07117 
07118                                 // Setup the Turrets.
07119                                 for ( i = 0; i < MAX_VEHICLE_TURRETS; i++ )
07120                                 {
07121                                         if ( cent->m_pVehicle->m_pVehicleInfo->turret[i].gunnerViewTag )
07122                                         {
07123                                                 cent->m_pVehicle->m_iGunnerViewTag[i] = trap_G2API_AddBolt( cent->ghoul2, 0, cent->m_pVehicle->m_pVehicleInfo->turret[i].gunnerViewTag );
07124                                         }
07125                                         else
07126                                         {
07127                                                 cent->m_pVehicle->m_iGunnerViewTag[i] = -1;
07128                                         }
07129                                 }
07130                         }
07131 
07132                         if (cent->currentState.npcSaber1)
07133                         {
07134                                 saber = (char *)CG_ConfigString(CS_MODELS+cent->currentState.npcSaber1);
07135                                 assert(!saber || !saber[0] || saber[0] == '@');
07136                                 //valid saber names should always start with '@' for NPCs
07137 
07138                                 if (saber && saber[0])
07139                                 {
07140                                         saber++; //skip over the @
07141                                         WP_SetSaber(cent->currentState.number, cent->npcClient->saber, 0, saber);
07142                                 }
07143                         }
07144                         if (cent->currentState.npcSaber2)
07145                         {
07146                                 saber = (char *)CG_ConfigString(CS_MODELS+cent->currentState.npcSaber2);
07147                                 assert(!saber || !saber[0] || saber[0] == '@');
07148                                 //valid saber names should always start with '@' for NPCs
07149 
07150                                 if (saber && saber[0])
07151                                 {
07152                                         saber++; //skip over the @
07153                                         WP_SetSaber(cent->currentState.number, cent->npcClient->saber, 1, saber);
07154                                 }
07155                         }
07156 
07157                         // If this is a not vehicle, give it saber stuff...
07158                         if ( cent->currentState.NPC_class != CLASS_VEHICLE )
07159                         {
07160                                 while (j < MAX_SABERS)
07161                                 {
07162                                         if (cent->npcClient->saber[j].model[0])
07163                                         {
07164                                                 if (cent->npcClient->ghoul2Weapons[j])
07165                                                 { //free the old instance(s)
07166                                                         trap_G2API_CleanGhoul2Models(&cent->npcClient->ghoul2Weapons[j]);
07167                                                         cent->npcClient->ghoul2Weapons[j] = 0;
07168                                                 }
07169 
07170                                                 CG_InitG2SaberData(j, cent->npcClient);
07171                                         }
07172                                         j++;
07173                                 }
07174                         }
07175 
07176                         trap_G2API_SetSkin(cent->ghoul2, 0, skinID, skinID);
07177 
07178                         cent->localAnimIndex = -1;
07179 
07180                         GLAName[0] = 0;
07181                         trap_G2API_GetGLAName(cent->ghoul2, 0, GLAName);
07182 
07183                         strcpy(originalModelName, modelName);
07184 
07185                         if (GLAName[0] &&
07186                                 !strstr(GLAName, "players/_humanoid/") /*&&
07187                                 !strstr(GLAName, "players/rockettrooper/")*/)
07188                         { //it doesn't use humanoid anims.                              
07189                                 slash = Q_strrchr( GLAName, '/' );
07190                                 if ( slash )
07191                                 {
07192                                         strcpy(slash, "/animation.cfg");
07193 
07194                                         cent->localAnimIndex = BG_ParseAnimationFile(GLAName, NULL, qfalse);
07195                                 }
07196                         }
07197                         else
07198                         { //humanoid index.
07199                                 trap_G2API_AddBolt(cent->ghoul2, 0, "*r_hand");
07200                                 trap_G2API_AddBolt(cent->ghoul2, 0, "*l_hand");
07201 
07202                                 //rhand must always be first bolt. lhand always second. Whichever you want the
07203                                 //jetpack bolted to must always be third.
07204                                 trap_G2API_AddBolt(cent->ghoul2, 0, "*chestg");
07205 
07206                                 //claw bolts
07207                                 trap_G2API_AddBolt(cent->ghoul2, 0, "*r_hand_cap_r_arm");
07208                                 trap_G2API_AddBolt(cent->ghoul2, 0, "*l_hand_cap_l_arm");
07209 
07210                                 if (strstr(GLAName, "players/rockettrooper/"))
07211                                 {
07212                                         cent->localAnimIndex = 1;
07213                                 }
07214                                 else
07215                                 {
07216                                         cent->localAnimIndex = 0;
07217                                 }
07218 
07219                                 if (trap_G2API_AddBolt(cent->ghoul2, 0, "*head_top") == -1)
07220                                 {
07221                                         trap_G2API_AddBolt(cent->ghoul2, 0, "ceyebrow");
07222                                 }
07223                                 trap_G2API_AddBolt(cent->ghoul2, 0, "Motion");
07224                         }
07225 
07226                         // If this is a not vehicle...
07227                         if ( cent->currentState.NPC_class != CLASS_VEHICLE )
07228                         {
07229                                 if (trap_G2API_AddBolt(cent->ghoul2, 0, "lower_lumbar") == -1)
07230                                 { //check now to see if we have this bone for setting anims and such
07231                                         cent->noLumbar = qtrue;
07232                                 }
07233 
07234                                 if (trap_G2API_AddBolt(cent->ghoul2, 0, "face") == -1)
07235                                 { //check now to see if we have this bone for setting anims and such
07236                                         cent->noFace = qtrue;
07237                                 }
07238                         }
07239                         else
07240                         {
07241                                 cent->noLumbar = qtrue;
07242                                 cent->noFace = qtrue;
07243                         }
07244 
07245                         if (cent->localAnimIndex != -1)
07246                         {
07247                                 slash = Q_strrchr( originalModelName, '/' );
07248                                 if ( slash )
07249                                 {
07250                                         slash++;
07251                                         *slash = 0;
07252                                 }
07253 
07254                                 cent->eventAnimIndex = BG_ParseAnimationEvtFile(originalModelName, cent->localAnimIndex, bgNumAnimEvents);
07255                         }
07256                 }
07257         }
07258 
07259         trap_S_ShutUp(qtrue);
07260         CG_HandleNPCSounds(cent); //handle sound loading here as well.
07261         trap_S_ShutUp(qfalse);
07262 }

int CG_G2EvIndexForModel void *  g2,
int  animIndex
 

Definition at line 770 of file cg_players.c.

References BG_ParseAnimationEvtFile(), bgNumAnimEvents, MAX_QPATH, Q_strrchr(), and trap_G2API_GetGLAName().

Referenced by CG_LoadClientInfo(), CG_NewClientInfo(), CG_Player(), and CG_ResetPlayerEntity().

00771 {
00772         int evtIndex = -1;
00773         char GLAName[MAX_QPATH];
00774         char *slash;
00775 
00776         if (animIndex == -1)
00777         {
00778                 assert(!"shouldn't happen, bad animIndex");
00779                 return -1;
00780         }
00781 
00782         GLAName[0] = 0;
00783         trap_G2API_GetGLAName(g2, 0, GLAName);
00784 
00785         slash = Q_strrchr( GLAName, '/' );
00786         if ( slash )
00787         {
00788                 slash++;
00789                 *slash = 0;
00790 
00791                 evtIndex = BG_ParseAnimationEvtFile(GLAName, animIndex, bgNumAnimEvents);
00792         }
00793 
00794         return evtIndex;
00795 }

qboolean CG_G2PlayerHeadAnims centity_t cent  ) 
 

Definition at line 4059 of file cg_players.c.

References centity_t, cg, cgs, cgs_t::clientinfo, centity_s::currentState, EF_DEAD, entityState_s::eFlags, FACE_ALERT, FACE_DEAD, FACE_FROWN, FACE_TALK1, clientInfo_t::facial_aux, clientInfo_t::facial_blink, clientInfo_t::facial_frown, flrand(), centity_s::localAnimIndex, MAX_CLIENTS, centity_s::noFace, centity_s::npcClient, NULL, entityState_s::number, qboolean, qfalse, qtrue, cg_t::time, and trap_S_GetVoiceVolume().

Referenced by CG_Player().

04060 {
04061         clientInfo_t *ci = NULL;
04062         int anim = -1;
04063         int voiceVolume = 0;
04064 
04065         if(cent->localAnimIndex > 1)
04066         { //only do this for humanoids
04067                 return qfalse;
04068         }
04069         
04070         if (cent->noFace)
04071         {       // i don't have a face
04072                 return qfalse;
04073         }
04074 
04075         if (cent->currentState.number < MAX_CLIENTS)
04076         {
04077                 ci = &cgs.clientinfo[cent->currentState.number];
04078         }
04079         else
04080         {
04081                 ci = cent->npcClient;
04082         }
04083 
04084         if (!ci)
04085         {
04086                 return qfalse;
04087         }
04088 
04089         if ( cent->currentState.eFlags & EF_DEAD )
04090         {//Dead people close their eyes and don't make faces!
04091                 anim = FACE_DEAD;
04092                 ci->facial_blink = -1;
04093         }
04094         else 
04095         {
04096                 if (!ci->facial_blink)
04097                 {       // set the timers
04098                         ci->facial_blink = cg.time + flrand(4000.0, 8000.0);
04099                         ci->facial_frown = cg.time + flrand(6000.0, 10000.0);
04100                         ci->facial_aux = cg.time + flrand(6000.0, 10000.0);
04101                 }
04102                 
04103                 //are we blinking?
04104                 if (ci->facial_blink < 0)
04105                 {       // yes, check if we are we done blinking ?
04106                         if (-(ci->facial_blink) < cg.time)
04107                         {       // yes, so reset blink timer
04108                                 ci->facial_blink = cg.time + flrand(4000.0, 8000.0);
04109                                 CG_G2SetHeadBlink( cent, qfalse );      //stop the blink
04110                         }
04111                 }
04112                 else // no we aren't blinking 
04113                 {       
04114                         if (ci->facial_blink < cg.time)// but should we start ?
04115                         {
04116                                 CG_G2SetHeadBlink( cent, qtrue );
04117                                 if (ci->facial_blink == 1)
04118                                 {//requested to stay shut by SET_FACEEYESCLOSED
04119                                         ci->facial_blink = -(cg.time + 99999999.0f);// set blink timer
04120                                 }
04121                                 else
04122                                 {
04123                                         ci->facial_blink = -(cg.time + 300.0f);// set blink timer
04124                                 }
04125                         } 
04126                 }
04127                 
04128                 voiceVolume = trap_S_GetVoiceVolume(cent->currentState.number);
04129 
04130                 if (voiceVolume > 0)    // if we aren't talking, then it will be 0, -1 for talking but paused
04131                 {
04132                         anim = FACE_TALK1 + voiceVolume -1;
04133                 }
04134                 else if (voiceVolume == 0)      //don't do aux if in a slient part of speech
04135                 {//not talking
04136                         if (ci->facial_aux < 0) // are we auxing ?
04137                         {       //yes
04138                                 if (-(ci->facial_aux) < cg.time)// are we done auxing ?
04139                                 {       // yes, reset aux timer
04140                                         ci->facial_aux = cg.time + flrand(7000.0, 10000.0);
04141                                 }
04142                                 else
04143                                 {       // not yet, so choose aux
04144                                         anim = FACE_ALERT;
04145                                 }
04146                         }
04147                         else // no we aren't auxing 
04148                         {       // but should we start ?
04149                                 if (ci->facial_aux < cg.time)
04150                                 {//yes
04151                                         anim = FACE_ALERT;
04152                                         // set aux timer
04153                                         ci->facial_aux = -(cg.time + 2000.0);
04154                                 } 
04155                         }       
04156                         
04157                         if (anim != -1) //we we are auxing, see if we should override with a frown
04158                         {       
04159                                 if (ci->facial_frown < 0)// are we frowning ?
04160                                 {       // yes, 
04161                                         if (-(ci->facial_frown) < cg.time)//are we done frowning ?
04162                                         {       // yes, reset frown timer
04163                                                 ci->facial_frown = cg.time + flrand(7000.0, 10000.0);
04164                                         }
04165                                         else 
04166                                         {       // not yet, so choose frown
04167                                                 anim = FACE_FROWN;
04168                                         }
04169                                 }
04170                                 else// no we aren't frowning 
04171                                 {       // but should we start ?
04172                                         if (ci->facial_frown < cg.time)
04173                                         {
04174                                                 anim = FACE_FROWN;
04175                                                 // set frown timer
04176                                                 ci->facial_frown = -(cg.time + 2000.0);
04177                                         }
04178                                 }
04179                         }
04180 
04181                 }//talking
04182         }//dead
04183         if (anim != -1)
04184         {
04185                 CG_G2SetHeadAnim( cent, anim );
04186                 return qtrue;
04187         }
04188         return qfalse;
04189 }

void CG_G2SaberEffects vec3_t  start,
vec3_t  end,
centity_t owner
 

Definition at line 5691 of file cg_players.c.

References centity_t, CG_G2TraceCollide(), CG_Trace(), cgs, CHAN_AUTO, centity_s::currentState, cgs_t::effects, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, MASK_PLAYERSOLID, MAX_CLIENTS, cgEffects_t::mSaberBloodSparks, cplane_s::normal, NULL, entityState_s::number, trace_t::plane, Q_irand(), qboolean, qfalse, qtrue, trap_FX_PlayEffectID(), trap_S_RegisterSound(), trap_S_StartSound(), va(), vec3_t, and VectorCopy.

Referenced by CG_AddSaberBlade().

05692 {
05693         trace_t trace;
05694         vec3_t startTr;
05695         vec3_t endTr;
05696         qboolean backWards = qfalse;
05697         qboolean doneWithTraces = qfalse;
05698 
05699         while (!doneWithTraces)
05700         {
05701                 if (!backWards)
05702                 {
05703                         VectorCopy(start, startTr);
05704                         VectorCopy(end, endTr);
05705                 }
05706                 else
05707                 {
05708                         VectorCopy(end, startTr);
05709                         VectorCopy(start, endTr);
05710                 }
05711 
05712                 CG_Trace( &trace, startTr, NULL, NULL, endTr, owner->currentState.number, MASK_PLAYERSOLID );
05713 
05714                 if (trace.entityNum < MAX_CLIENTS)
05715                 { //hit a client..
05716                         CG_G2TraceCollide(&trace, NULL, NULL, startTr, endTr);
05717 
05718                         if (trace.entityNum != ENTITYNUM_NONE)
05719                         { //it succeeded with the ghoul2 trace
05720                                 trap_FX_PlayEffectID( cgs.effects.mSaberBloodSparks, trace.endpos, trace.plane.normal, -1, -1 );
05721                                 trap_S_StartSound(trace.endpos, trace.entityNum, CHAN_AUTO, trap_S_RegisterSound(va("sound/weapons/saber/saberhit%i.wav", Q_irand(1, 3))));
05722                         }
05723                 }
05724 
05725                 if (!backWards)
05726                 {
05727                         backWards = qtrue;
05728                 }
05729                 else
05730                 {
05731                         doneWithTraces = qtrue;
05732                 }
05733         }
05734 }

void CG_G2ServerBoneAngles centity_t cent  ) 
 

Definition at line 3914 of file cg_players.c.

References BONE_ANGLES_POSTMULT, entityState_s::boneAngles1, entityState_s::boneAngles2, entityState_s::boneAngles3, entityState_s::boneAngles4, entityState_s::boneIndex1, entityState_s::boneIndex2, entityState_s::boneIndex3, entityState_s::boneIndex4, entityState_s::boneOrient, centity_t, cg, CG_ConfigString(), cgs, CS_G2BONES, centity_s::currentState, cgs_t::gameModels, centity_s::ghoul2, cg_t::time, trap_G2API_SetBoneAngles(), vec3_t, and VectorCopy.

03915 {
03916         int i = 0;
03917         int bone = cent->currentState.boneIndex1;
03918         int flags, up, right, forward;
03919         vec3_t boneAngles;
03920 
03921         VectorCopy(cent->currentState.boneAngles1, boneAngles);
03922 
03923         while (i < 4)
03924         { //cycle through the 4 bone index values on the entstate
03925                 if (bone)
03926                 { //if it's non-0 then it could have something in it.
03927                         const char *boneName = CG_ConfigString(CS_G2BONES+bone);
03928 
03929                         if (boneName && boneName[0])
03930                         { //got the bone, now set the angles from the corresponding entitystate boneangles value.
03931                                 flags = BONE_ANGLES_POSTMULT;
03932 
03933                                 //get the orientation out of our bit field
03934                                 forward = (cent->currentState.boneOrient)&7; //3 bits from bit 0
03935                                 right = (cent->currentState.boneOrient>>3)&7; //3 bits from bit 3
03936                                 up = (cent->currentState.boneOrient>>6)&7; //3 bits from bit 6
03937 
03938                                 trap_G2API_SetBoneAngles(cent->ghoul2, 0, boneName, boneAngles, flags, up, right, forward, cgs.gameModels, 100, cg.time);
03939                         }
03940                 }
03941 
03942                 switch (i)
03943                 {
03944                 case 0:
03945                         bone = cent->currentState.boneIndex2;
03946                         VectorCopy(cent->currentState.boneAngles2, boneAngles);
03947                         break;
03948                 case 1:
03949                         bone = cent->currentState.boneIndex3;
03950                         VectorCopy(cent->currentState.boneAngles3, boneAngles);
03951                         break;
03952                 case 2:
03953                         bone = cent->currentState.boneIndex4;
03954                         VectorCopy(cent->currentState.boneAngles4, boneAngles);
03955                         break;
03956                 default:
03957                         break;
03958                 }
03959 
03960                 i++;
03961         }
03962 }

void CG_G2SetBoneAngles void *  ghoul2,
int  modelIndex,
const char *  boneName,
const vec3_t  angles,
const int  flags,
const int  up,
const int  right,
const int  forward,
qhandle_t modelList,
int  blendTime,
int  currentTime
 

Definition at line 3365 of file cg_players.c.

References memset(), qhandle_t, qtrue, trap_G2API_SetBoneAngles(), and vec3_t.

Referenced by CG_RagDoll().

03368 { //we want to hold off on setting the bone angles until the end of the frame, because every time we set
03369   //them the entire skeleton has to be reconstructed.
03370 #if 0
03371         //This function should ONLY be called from CG_Player() or a function that is called only within CG_Player().
03372         //At the end of the frame we will check to use this information to call SetBoneAngles
03373         memset(&cgBoneAnglePostSet, 0, sizeof(cgBoneAnglePostSet));
03374         cgBoneAnglePostSet.ghoul2 = ghoul2;
03375         cgBoneAnglePostSet.modelIndex = modelIndex;
03376         cgBoneAnglePostSet.boneName = (char *)boneName;
03377 
03378         cgBoneAnglePostSet.angles[0] = angles[0];
03379         cgBoneAnglePostSet.angles[1] = angles[1];
03380         cgBoneAnglePostSet.angles[2] = angles[2];
03381 
03382         cgBoneAnglePostSet.flags = flags;
03383         cgBoneAnglePostSet.up = up;
03384         cgBoneAnglePostSet.right = right;
03385         cgBoneAnglePostSet.forward = forward;
03386         cgBoneAnglePostSet.modelList = modelList;
03387         cgBoneAnglePostSet.blendTime = blendTime;
03388         cgBoneAnglePostSet.currentTime = currentTime;
03389 
03390         cgBoneAnglePostSet.refreshSet = qtrue;
03391 #endif
03392         //We don't want to go with the delayed approach, we want out bolt points and everything to be updated in realtime.
03393         //We'll just take the reconstructs and live with them.
03394         trap_G2API_SetBoneAngles(ghoul2, modelIndex, boneName, angles, flags, up, right, forward, modelList,
03395                 blendTime, currentTime);
03396 }

int CG_G2SkelForModel void *  g2  ) 
 

Definition at line 749 of file cg_players.c.

References BG_ParseAnimationFile(), MAX_QPATH, NULL, Q_strrchr(), qfalse, strcpy(), and trap_G2API_GetGLAName().

Referenced by CG_LoadClientInfo(), CG_NewClientInfo(), CG_Player(), and CG_ResetPlayerEntity().

00750 {
00751         int animIndex = -1;
00752         char GLAName[MAX_QPATH];
00753         char *slash;
00754 
00755         GLAName[0] = 0;
00756         trap_G2API_GetGLAName(g2, 0, GLAName);
00757 
00758         slash = Q_strrchr( GLAName, '/' );
00759         if ( slash )
00760         {
00761                 strcpy(slash, "/animation.cfg");
00762 
00763                 animIndex = BG_ParseAnimationFile(GLAName, NULL, qfalse);
00764         }
00765 
00766         return animIndex;
00767 }

qboolean CG_G2TraceCollide trace_t tr,
vec3_t const  mins,
vec3_t const  maxs,
const vec3_t  lastValidStart,
const vec3_t  lastValidEnd
 

Definition at line 5632 of file cg_players.c.

References trace_t::allsolid, centity_t, cg, cg_entities, cg_g2TraceLod, cg_optvehtrace, CLASS_VEHICLE, centity_s::currentState, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, ET_NPC, entityState_s::eType, trace_t::fraction, G2Trace_t, centity_s::ghoul2, vmCvar_t::integer, centity_s::lerpAngles, centity_s::lerpOrigin, centity_s::m_pVehicle, MAX_G2_COLLISIONS, memset(), CollisionRecord_t::mEntityNum, centity_s::modelScale, cplane_s::normal, entityState_s::NPC_class, entityState_s::number, PITCH, trace_t::plane, qboolean, qfalse, qtrue, ROLL, trace_t::startsolid, cg_t::time, trap_G2API_CollisionDetect(), trap_G2API_CollisionDetectCache(), vec3_t, VectorCopy, and YAW.

Referenced by CG_G2SaberEffects(), and CG_SaberCompWork().

05633 {
05634         G2Trace_t               G2Trace;
05635         centity_t               *g2Hit;
05636         vec3_t                  angles;
05637         int                             tN = 0;
05638         float                   fRadius = 0.0f;
05639 
05640         if (mins && maxs &&
05641                 (mins[0] || maxs[0]))
05642         {
05643                 fRadius=(maxs[0]-mins[0])/2.0f;
05644         }
05645 
05646         memset (&G2Trace, 0, sizeof(G2Trace));
05647 
05648         while (tN < MAX_G2_COLLISIONS)
05649         {
05650                 G2Trace[tN].mEntityNum = -1;
05651                 tN++;
05652         }
05653         g2Hit = &cg_entities[tr->entityNum];
05654 
05655         if (g2Hit && g2Hit->ghoul2)
05656         {
05657                 angles[ROLL] = angles[PITCH] = 0;
05658                 angles[YAW] = g2Hit->lerpAngles[YAW];
05659 
05660                 if (cg_optvehtrace.integer &&
05661                         g2Hit->currentState.eType == ET_NPC &&
05662                         g2Hit->currentState.NPC_class == CLASS_VEHICLE &&
05663                         g2Hit->m_pVehicle)
05664                 {
05665                         trap_G2API_CollisionDetectCache ( G2Trace, g2Hit->ghoul2, angles, g2Hit->lerpOrigin, cg.time, g2Hit->currentState.number, lastValidStart, lastValidEnd, g2Hit->modelScale, 0, cg_g2TraceLod.integer, fRadius );
05666                 }
05667                 else
05668                 {
05669                         trap_G2API_CollisionDetect ( G2Trace, g2Hit->ghoul2, angles, g2Hit->lerpOrigin, cg.time, g2Hit->currentState.number, lastValidStart, lastValidEnd, g2Hit->modelScale, 0, cg_g2TraceLod.integer, fRadius );
05670                 }
05671 
05672                 if (G2Trace[0].mEntityNum != g2Hit->currentState.number)
05673                 {
05674                         tr->fraction = 1.0f;
05675                         tr->entityNum = ENTITYNUM_NONE;
05676                         tr->startsolid = 0;
05677                         tr->allsolid = 0;
05678                         return qfalse;
05679                 }
05680                 else
05681                 { //Yay!
05682                         VectorCopy(G2Trace[0].mCollisionPosition, tr->endpos);
05683                         VectorCopy(G2Trace[0].mCollisionNormal, tr->plane.normal);
05684                         return qtrue;
05685                 }
05686         }
05687 
05688         return qfalse;
05689 }

void CG_GetTagWorldPosition refEntity_t model,
char *  tag,
vec3_t  pos,
vec3_t  axis[3]
 

Definition at line 5437 of file cg_players.c.

References orientation_t::axis, refEntity_t::axis, refEntity_t::backlerp, refEntity_t::frame, refEntity_t::hModel, MatrixMultiply(), refEntity_t::oldframe, orientation_t::origin, refEntity_t::origin, trap_R_LerpTag(), vec3_t, VectorCopy, and VectorMA.

05438 {
05439         orientation_t   orientation;
05440         int i = 0;
05441 
05442         // Get the requested tag
05443         trap_R_LerpTag( &orientation, model->hModel, model->oldframe, model->frame,
05444                 1.0f - model->backlerp, tag );
05445 
05446         VectorCopy( model->origin, pos );
05447         for ( i = 0 ; i < 3 ; i++ ) 
05448         {
05449                 VectorMA( pos, orientation.origin[i], model->axis[i], pos );
05450         }
05451 
05452         if ( axis )
05453         {
05454                 MatrixMultiply( orientation.axis, model->axis, axis );
05455         }
05456 }

int CG_HandleAppendedSkin char *  modelName  ) 
 

Definition at line 6817 of file cg_players.c.

References MAX_QPATH, Q_strrchr(), qhandle_t, strchr(), strcpy(), trap_R_RegisterSkin(), and va().

Referenced by CG_G2AnimEntModelLoad().

06818 {
06819         char skinName[MAX_QPATH];
06820         char *p;
06821         qhandle_t skinID = 0;
06822         int i = 0;
06823 
06824         //see if it has a skin name
06825         p = Q_strrchr(modelName, '*');
06826 
06827         if (p)
06828         { //found a *, we should have a model name before it and a skin name after it.
06829                 *p = 0; //terminate the modelName string at this point, then go ahead and parse to the next 0 for the skin.
06830                 p++;
06831 
06832                 while (p && *p)
06833                 {
06834                         skinName[i] = *p;
06835                         i++;
06836                         p++;
06837                 }
06838                 skinName[i] = 0;
06839 
06840                 if (skinName[0]) 
06841                 { //got it, register the skin under the model path.
06842                         char baseFolder[MAX_QPATH];
06843 
06844                         strcpy(baseFolder, modelName);
06845                         p = Q_strrchr(baseFolder, '/'); //go back to the first /, should be the path point
06846 
06847                         if (p)
06848                         { //got it.. terminate at the slash and register.
06849                                 char *useSkinName;
06850 
06851                                 *p = 0;
06852 
06853                                 if (strchr(skinName, '|'))
06854                                 {//three part skin
06855                                         useSkinName = va("%s/|%s", baseFolder, skinName);
06856                                 }
06857                                 else
06858                                 {
06859                                         useSkinName = va("%s/model_%s.skin", baseFolder, skinName);
06860                                 }
06861 
06862                                 skinID = trap_R_RegisterSkin(useSkinName);
06863                         }
06864                 }
06865         }
06866 
06867         return skinID;
06868 }

void CG_HandleNPCSounds centity_t cent  ) 
 

Definition at line 484 of file cg_servercmds.c.

Referenced by CG_G2AnimEntModelLoad().

00485 {
00486         if (!cent->npcClient)
00487         {
00488                 return;
00489         }
00490 
00491         //standard
00492         if (cent->currentState.csSounds_Std)
00493         {
00494                 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Std );
00495 
00496                 if (s && s[0])
00497                 {
00498                         char sEnd[MAX_QPATH];
00499                         int i = 2;
00500                         int j = 0;
00501 
00502                         //Parse past the initial "*" which indicates this is a custom sound, and the $ which indicates
00503                         //it is an NPC custom sound dir.
00504                         while (s[i])
00505                         {
00506                                 sEnd[j] = s[i];
00507                                 j++;
00508                                 i++;
00509                         }
00510                         sEnd[j] = 0;
00511 
00512                         CG_RegisterCustomSounds(cent->npcClient, 1, sEnd);
00513                 }
00514         }
00515         else
00516         {
00517                 memset(&cent->npcClient->sounds, 0, sizeof(cent->npcClient->sounds));
00518         }
00519 
00520         //combat
00521         if (cent->currentState.csSounds_Combat)
00522         {
00523                 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Combat );
00524 
00525                 if (s && s[0])
00526                 {
00527                         char sEnd[MAX_QPATH];
00528                         int i = 2;
00529                         int j = 0;
00530 
00531                         //Parse past the initial "*" which indicates this is a custom sound, and the $ which indicates
00532                         //it is an NPC custom sound dir.
00533                         while (s[i])
00534                         {
00535                                 sEnd[j] = s[i];
00536                                 j++;
00537                                 i++;
00538                         }
00539                         sEnd[j] = 0;
00540 
00541                         CG_RegisterCustomSounds(cent->npcClient, 2, sEnd);
00542                 }
00543         }
00544         else
00545         {
00546                 memset(&cent->npcClient->combatSounds, 0, sizeof(cent->npcClient->combatSounds));
00547         }
00548 
00549         //extra
00550         if (cent->currentState.csSounds_Extra)
00551         {
00552                 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Extra );
00553 
00554                 if (s && s[0])
00555                 {
00556                         char sEnd[MAX_QPATH];
00557                         int i = 2;
00558                         int j = 0;
00559 
00560                         //Parse past the initial "*" which indicates this is a custom sound, and the $ which indicates
00561                         //it is an NPC custom sound dir.
00562                         while (s[i])
00563                         {
00564                                 sEnd[j] = s[i];
00565                                 j++;
00566                                 i++;
00567                         }
00568                         sEnd[j] = 0;
00569 
00570                         CG_RegisterCustomSounds(cent->npcClient, 3, sEnd);
00571                 }
00572         }
00573         else
00574         {
00575                 memset(&cent->npcClient->extraSounds, 0, sizeof(cent->npcClient->extraSounds));
00576         }
00577 
00578         //jedi
00579         if (cent->currentState.csSounds_Jedi)
00580         {
00581                 const char *s = CG_ConfigString( CS_SOUNDS + cent->currentState.csSounds_Jedi );
00582 
00583                 if (s && s[0])
00584                 {
00585                         char sEnd[MAX_QPATH];
00586                         int i = 2;
00587                         int j = 0;
00588 
00589                         //Parse past the initial "*" which indicates this is a custom sound, and the $ which indicates
00590                         //it is an NPC custom sound dir.
00591                         while (s[i])
00592                         {
00593                                 sEnd[j] = s[i];
00594                                 j++;
00595                                 i++;
00596                         }
00597                         sEnd[j] = 0;
00598 
00599                         CG_RegisterCustomSounds(cent->npcClient, 4, sEnd);
00600                 }
00601         }
00602         else
00603         {
00604                 memset(&cent->npcClient->jediSounds, 0, sizeof(cent->npcClient->jediSounds));
00605         }
00606 }

qboolean CG_InFighter void   ) 
 

Definition at line 5594 of file cg_draw.c.

References centity_t, cg, cg_entities, playerState_s::m_iVehicleNum, centity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, cg_t::predictedPlayerState, qboolean, qfalse, qtrue, vehicleInfo_t::type, and VH_FIGHTER.

Referenced by CG_EntityEvent(), and CG_Player().

05595 {
05596         if ( cg.predictedPlayerState.m_iVehicleNum )
05597         {//I'm in a vehicle
05598                 centity_t *vehCent = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
05599             if ( vehCent 
05600                         && vehCent->m_pVehicle 
05601                         && vehCent->m_pVehicle->m_pVehicleInfo
05602                         && vehCent->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER )
05603                 {//I'm in a fighter
05604                         return qtrue;
05605                 }
05606         }
05607         return qfalse;
05608 }

void CG_InitJetpackGhoul2 void   ) 
 

Definition at line 7882 of file cg_players.c.

References cg_g2JetpackInstance, JETPACK_MODEL, trap_G2API_AddBolt(), trap_G2API_InitGhoul2Model(), and trap_G2API_SetBoltInfo().

Referenced by CG_Init().

07883 {
07884         if (cg_g2JetpackInstance)
07885         {
07886                 assert(!"Tried to init jetpack inst, already init'd");
07887                 return;
07888         }
07889 
07890         trap_G2API_InitGhoul2Model(&cg_g2JetpackInstance, JETPACK_MODEL, 0, 0, 0, 0, 0);
07891 
07892         assert(cg_g2JetpackInstance);
07893 
07894         //Indicate which bolt on the player we will be attached to
07895         //In this case bolt 0 is rhand, 1 is lhand, and 2 is the bolt
07896         //for the jetpack (*chestg)
07897         trap_G2API_SetBoltInfo(cg_g2JetpackInstance, 0, 2);
07898 
07899         //Add the bolts jet effects will be played from
07900         trap_G2API_AddBolt(cg_g2JetpackInstance, 0, "torso_ljet");
07901         trap_G2API_AddBolt(cg_g2JetpackInstance, 0, "torso_rjet");
07902 }

qboolean CG_InRoll centity_t cent  ) 
 

Definition at line 2721 of file cg_players.c.

References lerpFrame_t::animationTime, BOTH_GETUP_BROLL_B, BOTH_GETUP_BROLL_F, BOTH_GETUP_BROLL_L, BOTH_GETUP_BROLL_R, BOTH_GETUP_FROLL_B, BOTH_GETUP_FROLL_F, BOTH_GETUP_FROLL_L, BOTH_GETUP_FROLL_R, BOTH_ROLL_B, BOTH_ROLL_F, BOTH_ROLL_L, BOTH_ROLL_R, centity_t, cg, centity_s::currentState, playerEntity_t::legs, entityState_s::legsAnim, centity_s::pe, qboolean, qfalse, qtrue, and cg_t::time.

02722 {
02723         switch ( (cent->currentState.legsAnim) )
02724         {
02725         case BOTH_GETUP_BROLL_B:
02726         case BOTH_GETUP_BROLL_F:
02727         case BOTH_GETUP_BROLL_L:
02728         case BOTH_GETUP_BROLL_R:
02729         case BOTH_GETUP_FROLL_B:
02730         case BOTH_GETUP_FROLL_F:
02731         case BOTH_GETUP_FROLL_L:
02732         case BOTH_GETUP_FROLL_R:
02733         case BOTH_ROLL_F:
02734         case BOTH_ROLL_B:
02735         case BOTH_ROLL_R:
02736         case BOTH_ROLL_L:
02737                 if ( cent->pe.legs.animationTime > cg.time )
02738                 {
02739                         return qtrue;
02740                 }
02741                 break;
02742         }
02743         return qfalse;
02744 }

qboolean CG_InRollAnim centity_t cent  ) 
 

Definition at line 2746 of file cg_players.c.

References BOTH_ROLL_B, BOTH_ROLL_F, BOTH_ROLL_L, BOTH_ROLL_R, centity_t, centity_s::currentState, entityState_s::legsAnim, qboolean, qfalse, and qtrue.

02747 {
02748         switch ( (cent->currentState.legsAnim) )
02749         {
02750         case BOTH_ROLL_F:
02751         case BOTH_ROLL_B:
02752         case BOTH_ROLL_R:
02753         case BOTH_ROLL_L:
02754                 return qtrue;
02755         }
02756         return qfalse;
02757 }

int CG_IsMindTricked int  trickIndex1,
int  trickIndex2,
int  trickIndex3,
int  trickIndex4,
int  client
 

Definition at line 6482 of file cg_players.c.

References cg_entities, client, and FP_SEE.

Referenced by CG_AddPlayerWeapon(), CG_AddRefEntityWithPowerups(), and CG_Player().

06483 {
06484         int checkIn;
06485         int sub = 0;
06486 
06487         if (cg_entities[client].currentState.forcePowersActive & (1 << FP_SEE))
06488         {
06489                 return 0;
06490         }
06491 
06492         if (client > 47)
06493         {
06494                 checkIn = trickIndex4;
06495                 sub = 48;
06496         }
06497         else if (client > 31)
06498         {
06499                 checkIn = trickIndex3;
06500                 sub = 32;
06501         }
06502         else if (client > 15)
06503         {
06504                 checkIn = trickIndex2;
06505                 sub = 16;
06506         }
06507         else
06508         {
06509                 checkIn = trickIndex1;
06510         }
06511 
06512         if (checkIn & (1 << (client-sub)))
06513         {
06514                 return 1;
06515         }
06516         
06517         return 0;
06518 }

int CG_LightVerts vec3_t  normal,
int  numVerts,
polyVert_t verts
 

Definition at line 5167 of file cg_players.c.

References DotProduct, polyVert_t::modulate, qtrue, trap_R_LightForPoint(), and vec3_t.

05168 {
05169         int                             i, j;
05170         float                   incoming;
05171         vec3_t                  ambientLight;
05172         vec3_t                  lightDir;
05173         vec3_t                  directedLight;
05174 
05175         trap_R_LightForPoint( verts[0].xyz, ambientLight, directedLight, lightDir );
05176 
05177         for (i = 0; i < numVerts; i++) {
05178                 incoming = DotProduct (normal, lightDir);
05179                 if ( incoming <= 0 ) {
05180                         verts[i].modulate[0] = ambientLight[0];
05181                         verts[i].modulate[1] = ambientLight[1];
05182                         verts[i].modulate[2] = ambientLight[2];
05183                         verts[i].modulate[3] = 255;
05184                         continue;
05185                 } 
05186                 j = ( ambientLight[0] + incoming * directedLight[0] );
05187                 if ( j > 255 ) {
05188                         j = 255;
05189                 }
05190                 verts[i].modulate[0] = j;
05191 
05192                 j = ( ambientLight[1] + incoming * directedLight[1] );
05193                 if ( j > 255 ) {
05194                         j = 255;
05195                 }
05196                 verts[i].modulate[1] = j;
05197 
05198                 j = ( ambientLight[2] + incoming * directedLight[2] );
05199                 if ( j > 255 ) {
05200                         j = 255;
05201                 }
05202                 verts[i].modulate[2] = j;
05203 
05204                 verts[i].modulate[3] = 255;
05205         }
05206         return qtrue;
05207 }

void CG_LoadCISounds clientInfo_t ci,
qboolean  modelloaded
 

Definition at line 799 of file cg_players.c.

References bg_customSiegeSoundNames, cg_buildScript, cg_customDuelSoundNames, cg_customSoundNames, cgs, Com_sprintf(), COM_StripExtension(), DEFAULT_FEMALE_SOUNDPATH, DEFAULT_MALE_SOUNDPATH, clientInfo_t::duelSounds, fileHandle_t, FS_READ, cgs_t::gametype, clientInfo_t::gender, GENDER_FEMALE, GENDER_MALE, GT_DUEL, GT_POWERDUEL, GT_TEAM, vmCvar_t::integer, MAX_CUSTOM_DUEL_SOUNDS, MAX_CUSTOM_SIEGE_SOUNDS, MAX_CUSTOM_SOUNDS, MAX_QPATH, clientInfo_t::modelName, Q_stricmp(), qboolean, qfalse, qtrue, clientInfo_t::siegeSounds, clientInfo_t::skinName, clientInfo_t::sounds, trap_FS_FCloseFile(), trap_FS_FOpenFile(), trap_FS_Read(), trap_S_RegisterSound(), trap_S_ShutUp(), and va().

Referenced by CG_LoadClientInfo(), and CG_PrecachePlayersForSiegeTeam().

00800 {
00801         fileHandle_t f;
00802         qboolean        isFemale = qfalse;
00803         int                     i = 0;
00804         int                     fLen = 0;
00805         const char      *dir;
00806         char            soundpath[MAX_QPATH];
00807         char            soundName[1024];
00808         const char      *s;
00809 
00810         dir = ci->modelName;
00811 
00812         if ( !ci->skinName || !Q_stricmp( "default", ci->skinName ) )
00813         {//try default sounds.cfg first
00814                 fLen = trap_FS_FOpenFile(va("models/players/%s/sounds.cfg", dir), &f, FS_READ);
00815                 if ( !f ) 
00816                 {//no?  Look for _default sounds.cfg
00817                         fLen = trap_FS_FOpenFile(va("models/players/%s/sounds_default.cfg", dir), &f, FS_READ);
00818                 }
00819         }
00820         else
00821         {//use the .skin associated with this skin
00822                 fLen = trap_FS_FOpenFile(va("models/players/%s/sounds_%s.cfg", dir, ci->skinName), &f, FS_READ);
00823                 if ( !f ) 
00824                 {//fall back to default sounds
00825                         fLen = trap_FS_FOpenFile(va("models/players/%s/sounds.cfg", dir), &f, FS_READ);
00826                 }
00827         }
00828 
00829         soundpath[0] = 0;
00830 
00831         if (f)
00832         {
00833                 trap_FS_Read(soundpath, fLen, f);
00834                 soundpath[fLen] = 0;
00835 
00836                 i = fLen;
00837 
00838                 while (i >= 0 && soundpath[i] != '\n')
00839                 {
00840                         if (soundpath[i] == 'f')
00841                         {
00842                                 isFemale = qtrue;
00843                                 soundpath[i] = 0;
00844                         }
00845 
00846                         i--;
00847                 }
00848 
00849                 i = 0;
00850 
00851                 while (soundpath[i] && soundpath[i] != '\r' && soundpath[i] != '\n')
00852                 {
00853                         i++;
00854                 }
00855                 soundpath[i] = 0;
00856 
00857                 trap_FS_FCloseFile(f);
00858         }
00859 
00860         if (isFemale)
00861         {
00862                 ci->gender = GENDER_FEMALE;
00863         }
00864         else
00865         {
00866                 ci->gender = GENDER_MALE;
00867         }
00868 
00869         trap_S_ShutUp(qtrue);
00870 
00871         for ( i = 0 ; i < MAX_CUSTOM_SOUNDS ; i++ )
00872         {
00873                 s = cg_customSoundNames[i];
00874                 if ( !s ) {
00875                         break;
00876                 }
00877 
00878                 Com_sprintf(soundName, sizeof(soundName), "%s", s+1);
00879                 COM_StripExtension(soundName, soundName);
00880                 //strip the extension because we might want .mp3's
00881 
00882                 ci->sounds[i] = 0;
00883                 // if the model didn't load use the sounds of the default model
00884                 if (soundpath[0])
00885                 {
00886                         ci->sounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", soundpath, soundName) );
00887                 }
00888                 else
00889                 {
00890                         if (modelloaded)
00891                         {
00892                                 ci->sounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", dir, soundName) );
00893                         }
00894                 }
00895 
00896                 if (!ci->sounds[i])
00897                 { //failed the load, try one out of the generic path
00898                         if (isFemale)
00899                         {
00900                                 ci->sounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_FEMALE_SOUNDPATH, soundName) );
00901                         }
00902                         else
00903                         {
00904                                 ci->sounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_MALE_SOUNDPATH, soundName) );
00905                         }
00906                 }
00907         }
00908 
00909         if (cgs.gametype >= GT_TEAM || cg_buildScript.integer)
00910         { //load the siege sounds then
00911                 for ( i = 0 ; i < MAX_CUSTOM_SIEGE_SOUNDS; i++ )
00912                 {
00913                         s = bg_customSiegeSoundNames[i];
00914                         if ( !s )
00915                         {
00916                                 break;
00917                         }
00918 
00919                         Com_sprintf(soundName, sizeof(soundName), "%s", s+1);
00920                         COM_StripExtension(soundName, soundName);
00921                         //strip the extension because we might want .mp3's
00922 
00923                         ci->siegeSounds[i] = 0;
00924                         // if the model didn't load use the sounds of the default model
00925                         if (soundpath[0])
00926                         {
00927                                 ci->siegeSounds[i] = trap_S_RegisterSound( va("sound/%s/%s", soundpath, soundName) );
00928                         }
00929                         else
00930                         {
00931                                 if (modelloaded)
00932                                 {
00933                                         ci->siegeSounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", dir, soundName) );
00934                                 }
00935                         }
00936 
00937                         if (!ci->siegeSounds[i])
00938                         { //failed the load, try one out of the generic path
00939                                 if (isFemale)
00940                                 {
00941                                         ci->siegeSounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_FEMALE_SOUNDPATH, soundName) );
00942                                 }
00943                                 else
00944                                 {
00945                                         ci->siegeSounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_MALE_SOUNDPATH, soundName) );
00946                                 }
00947                         }
00948                 }
00949         }
00950 
00951         if (cgs.gametype == GT_DUEL
00952                 ||cgs.gametype == GT_POWERDUEL
00953                 || cg_buildScript.integer)
00954         { //load the Duel sounds then
00955                 for ( i = 0 ; i < MAX_CUSTOM_DUEL_SOUNDS; i++ )
00956                 {
00957                         s = cg_customDuelSoundNames[i];
00958                         if ( !s )
00959                         {
00960                                 break;
00961                         }
00962 
00963                         Com_sprintf(soundName, sizeof(soundName), "%s", s+1);
00964                         COM_StripExtension(soundName, soundName);
00965                         //strip the extension because we might want .mp3's
00966 
00967                         ci->duelSounds[i] = 0;
00968                         // if the model didn't load use the sounds of the default model
00969                         if (soundpath[0])
00970                         {
00971                                 ci->duelSounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", soundpath, soundName) );
00972                         }
00973                         else
00974                         {
00975                                 if (modelloaded)
00976                                 {
00977                                         ci->duelSounds[i] = trap_S_RegisterSound( va("sound/chars/%s/misc/%s", dir, soundName) );
00978                                 }
00979                         }
00980 
00981                         if (!ci->duelSounds[i])
00982                         { //failed the load, try one out of the generic path
00983                                 if (isFemale)
00984                                 {
00985                                         ci->duelSounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_FEMALE_SOUNDPATH, soundName) );
00986                                 }
00987                                 else
00988                                 {
00989                                         ci->duelSounds[i] = trap_S_RegisterSound( va("sound/%s/%s", DEFAULT_MALE_SOUNDPATH, soundName) );
00990                                 }
00991                         }
00992                 }
00993         }
00994 
00995         trap_S_ShutUp(qfalse);
00996 }

void CG_LoadClientInfo clientInfo_t ci  ) 
 

Definition at line 1006 of file cg_players.c.

References cg_entities, CG_Error(), CG_G2EvIndexForModel(), CG_G2SkelForModel(), CG_LoadCISounds(), CG_ResetPlayerEntity(), cgs, cgs_t::clientinfo, entityState_s::clientNum, centity_s::currentState, DEFAULT_BLUETEAM_NAME, DEFAULT_MODEL, DEFAULT_REDTEAM_NAME, clientInfo_t::deferred, ET_PLAYER, entityState_s::eType, centity_s::eventAnimIndex, cgs_t::gametype, centity_s::ghoul2, clientInfo_t::ghoul2Model, GT_SIEGE, GT_TEAM, centity_s::localAnimIndex, MAX_CLIENTS, MAX_GENTITIES, MAX_QPATH, clientInfo_t::modelName, clientInfo_t::newAnims, centity_s::noFace, Q_strncpyz(), qboolean, qfalse, qtrue, clientInfo_t::siegeIndex, clientInfo_t::skinName, strcat(), clientInfo_t::team, TEAM_BLUE, TEAM_SPECTATOR, clientInfo_t::torsoModel, trap_G2_HaveWeGhoul2Models(), trap_G2API_AddBolt(), trap_G2API_AttachInstanceToEntNum(), trap_G2API_CleanGhoul2Models(), trap_G2API_ClearAttachedInstance(), trap_G2API_DuplicateGhoul2Instance(), and trap_R_LerpTag().

Referenced by CG_ActualLoadDeferredPlayers(), and CG_NewClientInfo().

01006                                            {
01007         qboolean        modelloaded;
01008         int                     clientNum;
01009         int                     i;
01010         char            teamname[MAX_QPATH];
01011 
01012         clientNum = ci - cgs.clientinfo;
01013 
01014         if (clientNum < 0 || clientNum >= MAX_CLIENTS)
01015         {
01016                 clientNum = -1;
01017         }
01018 
01019         ci->deferred = qfalse;
01020 
01021         /*
01022         if (ci->team == TEAM_SPECTATOR)
01023         {
01024                 // reset any existing players and bodies, because they might be in bad
01025                 // frames for this new model
01026                 clientNum = ci - cgs.clientinfo;
01027                 for ( i = 0 ; i < MAX_GENTITIES ; i++ ) {
01028                         if ( cg_entities[i].currentState.clientNum == clientNum
01029                                 && cg_entities[i].currentState.eType == ET_PLAYER ) {
01030                                 CG_ResetPlayerEntity( &cg_entities[i] );
01031                         }
01032                 }
01033 
01034                 if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
01035                 {
01036                         trap_G2API_CleanGhoul2Models(&ci->ghoul2Model);
01037                 }
01038 
01039                 return;
01040         }
01041         */
01042 
01043         teamname[0] = 0;
01044         if( cgs.gametype >= GT_TEAM) {
01045                 if( ci->team == TEAM_BLUE ) {
01046                         Q_strncpyz(teamname, DEFAULT_BLUETEAM_NAME/*cg_blueTeamName.string*/, sizeof(teamname) );
01047                 } else {
01048                         Q_strncpyz(teamname, DEFAULT_REDTEAM_NAME/*cg_redTeamName.string*/, sizeof(teamname) );
01049                 }
01050         }
01051         if( teamname[0] ) {
01052                 strcat( teamname, "/" );
01053         }
01054         modelloaded = qtrue;
01055         if (cgs.gametype == GT_SIEGE &&
01056                 (ci->team == TEAM_SPECTATOR || ci->siegeIndex == -1))
01057         { //yeah.. kind of a hack I guess. Don't care until they are actually ingame with a valid class.
01058                 if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default", teamname, -1 ) )
01059                 {
01060                         CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL );
01061                 }
01062         }
01063         else
01064         {
01065                 if ( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName, teamname, clientNum ) ) {
01066                         //CG_Error( "CG_RegisterClientModelname( %s, %s, %s, %s %s ) failed", ci->modelName, ci->skinName, ci->headModelName, ci->headSkinName, teamname );
01067                         //rww - DO NOT error out here! Someone could just type in a nonsense model name and crash everyone's client.
01068                         //Give it a chance to load default model for this client instead.
01069 
01070                         // fall back to default team name
01071                         if( cgs.gametype >= GT_TEAM) {
01072                                 // keep skin name
01073                                 if( ci->team == TEAM_BLUE ) {
01074                                         Q_strncpyz(teamname, DEFAULT_BLUETEAM_NAME, sizeof(teamname) );
01075                                 } else {
01076                                         Q_strncpyz(teamname, DEFAULT_REDTEAM_NAME, sizeof(teamname) );
01077                                 }
01078                                 if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, ci->skinName, teamname, -1 ) ) {
01079                                         CG_Error( "DEFAULT_MODEL / skin (%s/%s) failed to register", DEFAULT_MODEL, ci->skinName );
01080                                 }
01081                         } else {
01082                                 if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default", teamname, -1 ) ) {
01083                                         CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL );
01084                                 }
01085                         }
01086                         modelloaded = qfalse;
01087                 }
01088         }
01089 
01090         if (clientNum != -1)
01091         {
01092                 trap_G2API_ClearAttachedInstance(clientNum);
01093         }
01094 
01095         if (clientNum != -1 && ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
01096         {
01097                 if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2))
01098                 {
01099                         trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2);
01100                 }
01101                 trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2);
01102 
01103                 //Attach the instance to this entity num so we can make use of client-server
01104                 //shared operations if possible.
01105                 trap_G2API_AttachInstanceToEntNum(cg_entities[clientNum].ghoul2, clientNum, qfalse);
01106 
01107 
01108                 if (trap_G2API_AddBolt(cg_entities[clientNum].ghoul2, 0, "face") == -1)
01109                 { //check now to see if we have this bone for setting anims and such
01110                         cg_entities[clientNum].noFace = qtrue;
01111                 }
01112 
01113                 cg_entities[clientNum].localAnimIndex = CG_G2SkelForModel(cg_entities[clientNum].ghoul2);
01114                 cg_entities[clientNum].eventAnimIndex = CG_G2EvIndexForModel(cg_entities[clientNum].ghoul2, cg_entities[clientNum].localAnimIndex);
01115         }
01116 
01117         ci->newAnims = qfalse;
01118         if ( ci->torsoModel ) {
01119                 orientation_t tag;
01120                 // if the torso model has the "tag_flag"
01121                 if ( trap_R_LerpTag( &tag, ci->torsoModel, 0, 0, 1, "tag_flag" ) ) {
01122                         ci->newAnims = qtrue;
01123                 }
01124         }
01125 
01126         // sounds
01127         if (cgs.gametype == GT_SIEGE &&
01128                 (ci->team == TEAM_SPECTATOR || ci->siegeIndex == -1))
01129         { //don't need to load sounds
01130         }
01131         else
01132         {
01133                 CG_LoadCISounds(ci, modelloaded);
01134         }
01135 
01136         ci->deferred = qfalse;
01137 
01138         // reset any existing players and bodies, because they might be in bad
01139         // frames for this new model
01140         clientNum = ci - cgs.clientinfo;
01141         for ( i = 0 ; i < MAX_GENTITIES ; i++ ) {
01142                 if ( cg_entities[i].currentState.clientNum == clientNum
01143                         && cg_entities[i].currentState.eType == ET_PLAYER ) {
01144                         CG_ResetPlayerEntity( &cg_entities[i] );
01145                 }
01146         }
01147 }

void CG_LoadDeferredPlayers void   ) 
 

Definition at line 1976 of file cg_players.c.

References cgQueueLoad, and qtrue.

Referenced by CG_DrawOldScoreboard().

01976                                     {
01977         cgQueueLoad = qtrue;
01978 }

void CG_NewClientInfo int  clientNum,
qboolean  entitiesInitialized
 

Definition at line 1503 of file cg_players.c.

References animation_t, atoi(), BG_SI_SetDesiredLength(), BG_SiegeFindClassByName(), BG_SiegeFindClassIndexByName(), BG_ValidateSkinForTeam(), bgHumanoidAnimations, saberInfo_t::blade, BONE_ANIM_OVERRIDE_FREEZE, BONE_ANIM_OVERRIDE_LOOP, clientInfo_t::botSkill, centity_t, cg, cg_buildScript, CG_ConfigString(), CG_CopyG2WeaponInstance(), cg_deferPlayers, cg_entities, cg_forceModel, CG_G2EvIndexForModel(), CG_G2SkelForModel(), CG_G2WeaponInstance(), CG_LoadClientInfo(), cgs, cgs_t::clientinfo, playerState_s::clientNum, cg_t::clientNum, clientInfo_t::color1, clientInfo_t::color2, clientInfo_t::colorOverride, CS_PLAYERS, centity_s::currentState, clientInfo_t::duelTeam, centity_s::eventAnimIndex, animation_s::firstFrame, siegeClass_t::forcedModel, siegeClass_t::forcedSaber2Color, siegeClass_t::forcedSaberColor, siegeClass_t::forcedSkin, clientInfo_t::forcePowers, lerpFrame_t::frame, animation_s::frameLerp, cgs_t::gametype, centity_s::ghoul2, clientInfo_t::ghoul2Model, centity_s::ghoul2weapon, clientInfo_t::ghoul2Weapons, GT_SIEGE, GT_TEAM, clientInfo_t::handicap, siegeClass_t::hasForcedSaber2Color, siegeClass_t::hasForcedSaberColor, clientInfo_t::icolor1, clientInfo_t::icolor2, Info_ValueForKey(), clientInfo_t::infoValid, vmCvar_t::integer, cgs_t::jediVmerc, playerEntity_t::legs, entityState_s::legsAnim, bladeInfo_t::length, bladeInfo_t::lengthMax, cg_t::loading, centity_s::localAnimIndex, animation_s::loopFrames, clientInfo_t::losses, MAX_CLIENTS, MAX_QPATH, MAX_SABERS, memcpy(), memset(), saberInfo_t::model, clientInfo_t::modelName, clientInfo_t::name, centity_s::noFace, NULL, entityState_s::number, saberInfo_t::numBlades, animation_s::numFrames, centity_s::pe, cg_t::predictedPlayerState, snapshot_t::ps, Q_stricmp(), Q_strncpyz(), qboolean, qfalse, qtrue, clientInfo_t::saber, clientInfo_t::saber2Name, entityState_s::saberHolstered, clientInfo_t::saberName, clientInfo_t::siegeDesiredTeam, clientInfo_t::siegeIndex, clientInfo_t::skinName, cg_t::snap, strchr(), clientInfo_t::team, clientInfo_t::teamLeader, clientInfo_t::teamTask, cg_t::time, playerEntity_t::torso, entityState_s::torsoAnim, trap_Cvar_Set(), trap_Cvar_VariableStringBuffer(), trap_G2_HaveWeGhoul2Models(), trap_G2API_AddBolt(), trap_G2API_AttachInstanceToEntNum(), trap_G2API_CleanGhoul2Models(), trap_G2API_ClearAttachedInstance(), trap_G2API_DuplicateGhoul2Instance(), trap_G2API_SetBoneAnim(), entityState_s::weapon, centity_s::weapon, clientInfo_t::wins, WP_SABER, and WP_SetSaber().

01503                                                                      {
01504         clientInfo_t *ci;
01505         clientInfo_t newInfo;
01506         const char      *configstring;
01507         const char      *v;
01508         char            *slash;
01509         void *oldGhoul2;
01510         void *oldG2Weapons[MAX_SABERS];
01511         int i = 0;
01512         int k = 0;
01513         qboolean saberUpdate[MAX_SABERS];
01514 
01515         ci = &cgs.clientinfo[clientNum];
01516 
01517         oldGhoul2 = ci->ghoul2Model;
01518 
01519         while (k < MAX_SABERS)
01520         {
01521                 oldG2Weapons[k] = ci->ghoul2Weapons[k];
01522                 k++;
01523         }
01524 
01525         configstring = CG_ConfigString( clientNum + CS_PLAYERS );
01526         if ( !configstring[0] ) {
01527                 if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
01528                 { //clean this stuff up first
01529                         trap_G2API_CleanGhoul2Models(&ci->ghoul2Model);
01530                 }
01531                 k = 0;
01532                 while (k < MAX_SABERS)
01533                 {
01534                         if (ci->ghoul2Weapons[k] && trap_G2_HaveWeGhoul2Models(ci->ghoul2Weapons[k]))
01535                         {
01536                                 trap_G2API_CleanGhoul2Models(&ci->ghoul2Weapons[k]);
01537                         }
01538                         k++;
01539                 }
01540 
01541                 memset( ci, 0, sizeof( *ci ) );
01542                 return;         // player just left
01543         }
01544 
01545         // build into a temp buffer so the defer checks can use
01546         // the old value
01547         memset( &newInfo, 0, sizeof( newInfo ) );
01548 
01549         // isolate the player's name
01550         v = Info_ValueForKey(configstring, "n");
01551         Q_strncpyz( newInfo.name, v, sizeof( newInfo.name ) );
01552 
01553         // colors
01554         v = Info_ValueForKey( configstring, "c1" );
01555         CG_ColorFromString( v, newInfo.color1 );
01556 
01557         newInfo.icolor1 = atoi(v);
01558 
01559         v = Info_ValueForKey( configstring, "c2" );
01560         CG_ColorFromString( v, newInfo.color2 );
01561 
01562         newInfo.icolor2 = atoi(v);
01563 
01564         // bot skill
01565         v = Info_ValueForKey( configstring, "skill" );
01566         newInfo.botSkill = atoi( v );
01567 
01568         // handicap
01569         v = Info_ValueForKey( configstring, "hc" );
01570         newInfo.handicap = atoi( v );
01571 
01572         // wins
01573         v = Info_ValueForKey( configstring, "w" );
01574         newInfo.wins = atoi( v );
01575 
01576         // losses
01577         v = Info_ValueForKey( configstring, "l" );
01578         newInfo.losses = atoi( v );
01579 
01580         // team
01581         v = Info_ValueForKey( configstring, "t" );
01582         newInfo.team = atoi( v );
01583 
01584 //copy team info out to menu
01585         if ( clientNum == cg.clientNum) //this is me
01586         {
01587                 trap_Cvar_Set("ui_team", v);
01588         }
01589 
01590         // team task
01591         v = Info_ValueForKey( configstring, "tt" );
01592         newInfo.teamTask = atoi(v);
01593 
01594         // team leader
01595         v = Info_ValueForKey( configstring, "tl" );
01596         newInfo.teamLeader = atoi(v);
01597 
01598 //      v = Info_ValueForKey( configstring, "g_redteam" );
01599 //      Q_strncpyz(newInfo.redTeam, v, MAX_TEAMNAME);
01600 
01601 //      v = Info_ValueForKey( configstring, "g_blueteam" );
01602 //      Q_strncpyz(newInfo.blueTeam, v, MAX_TEAMNAME);
01603 
01604         // model
01605         v = Info_ValueForKey( configstring, "model" );
01606         if ( cg_forceModel.integer ) {
01607                 // forcemodel makes everyone use a single model
01608                 // to prevent load hitches
01609                 char modelStr[MAX_QPATH];
01610                 char *skin;
01611 
01612                 trap_Cvar_VariableStringBuffer( "model", modelStr, sizeof( modelStr ) );
01613                 if ( ( skin = strchr( modelStr, '/' ) ) == NULL) {
01614                         skin = "default";
01615                 } else {
01616                         *skin++ = 0;
01617                 }
01618                 Q_strncpyz( newInfo.skinName, skin, sizeof( newInfo.skinName ) );
01619                 Q_strncpyz( newInfo.modelName, modelStr, sizeof( newInfo.modelName ) );
01620 
01621                 if ( cgs.gametype >= GT_TEAM ) {
01622                         // keep skin name
01623                         slash = strchr( v, '/' );
01624                         if ( slash ) {
01625                                 Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
01626                         }
01627                 }
01628         } else {
01629                 Q_strncpyz( newInfo.modelName, v, sizeof( newInfo.modelName ) );
01630 
01631                 slash = strchr( newInfo.modelName, '/' );
01632                 if ( !slash ) {
01633                         // modelName didn not include a skin name
01634                         Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) );
01635                 } else {
01636                         Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
01637                         // truncate modelName
01638                         *slash = 0;
01639                 }
01640         }
01641 
01642         if (cgs.gametype == GT_SIEGE)
01643         { //entries only sent in siege mode
01644                 //siege desired team
01645                 v = Info_ValueForKey( configstring, "sdt" );
01646                 if (v && v[0])
01647                 {
01648             newInfo.siegeDesiredTeam = atoi(v);
01649                 }
01650                 else
01651                 {
01652                         newInfo.siegeDesiredTeam = 0;
01653                 }
01654 
01655                 //siege classname
01656                 v = Info_ValueForKey( configstring, "siegeclass" );
01657                 newInfo.siegeIndex = -1;
01658 
01659                 if (v)
01660                 {
01661                         siegeClass_t *siegeClass = BG_SiegeFindClassByName(v);
01662 
01663                         if (siegeClass)
01664                         { //See if this class forces a model, if so, then use it. Same for skin.
01665                                 newInfo.siegeIndex = BG_SiegeFindClassIndexByName(v);
01666 
01667                                 if (siegeClass->forcedModel[0])
01668                                 {
01669                                         Q_strncpyz( newInfo.modelName, siegeClass->forcedModel, sizeof( newInfo.modelName ) );
01670                                 }
01671 
01672                                 if (siegeClass->forcedSkin[0])
01673                                 {
01674                                         Q_strncpyz( newInfo.skinName, siegeClass->forcedSkin, sizeof( newInfo.skinName ) );
01675                                 }
01676 
01677                                 if (siegeClass->hasForcedSaberColor)
01678                                 {
01679                                         newInfo.icolor1 = siegeClass->forcedSaberColor;
01680 
01681                                         CG_ColorFromInt( newInfo.icolor1, newInfo.color1 );
01682                                 }
01683                                 if (siegeClass->hasForcedSaber2Color)
01684                                 {
01685                                         newInfo.icolor2 = siegeClass->forcedSaber2Color;
01686 
01687                                         CG_ColorFromInt( newInfo.icolor2, newInfo.color2 );
01688                                 }
01689                         }
01690                 }
01691         }
01692 
01693         saberUpdate[0] = qfalse;
01694         saberUpdate[1] = qfalse;
01695 
01696         //saber being used
01697         v = Info_ValueForKey( configstring, "st" );
01698 
01699         if (v && Q_stricmp(v, ci->saberName))
01700         {
01701                 Q_strncpyz( newInfo.saberName, v, 64 );
01702                 WP_SetSaber(clientNum, newInfo.saber, 0, newInfo.saberName);
01703                 saberUpdate[0] = qtrue;
01704         }
01705         else
01706         {
01707                 Q_strncpyz( newInfo.saberName, ci->saberName, 64 );
01708                 memcpy(&newInfo.saber[0], &ci->saber[0], sizeof(newInfo.saber[0]));
01709                 newInfo.ghoul2Weapons[0] = ci->ghoul2Weapons[0];
01710         }
01711 
01712         v = Info_ValueForKey( configstring, "st2" );
01713 
01714         if (v && Q_stricmp(v, ci->saber2Name))
01715         {
01716                 Q_strncpyz( newInfo.saber2Name, v, 64 );
01717                 WP_SetSaber(clientNum, newInfo.saber, 1, newInfo.saber2Name);
01718                 saberUpdate[1] = qtrue;
01719         }
01720         else
01721         {
01722                 Q_strncpyz( newInfo.saber2Name, ci->saber2Name, 64 );
01723                 memcpy(&newInfo.saber[1], &ci->saber[1], sizeof(newInfo.saber[1]));
01724                 newInfo.ghoul2Weapons[1] = ci->ghoul2Weapons[1];
01725         }
01726 
01727         if (saberUpdate[0] || saberUpdate[1])
01728         {
01729                 int j = 0;
01730 
01731                 while (j < MAX_SABERS)
01732                 {
01733                         if (saberUpdate[j])
01734                         {
01735                                 if (newInfo.saber[j].model[0])
01736                                 {
01737                                         if (oldG2Weapons[j])
01738                                         { //free the old instance(s)
01739                                                 trap_G2API_CleanGhoul2Models(&oldG2Weapons[j]);
01740                                                 oldG2Weapons[j] = 0;
01741                                         }
01742 
01743                                         CG_InitG2SaberData(j, &newInfo);
01744                                 }
01745                                 else
01746                                 {
01747                                         if (oldG2Weapons[j])
01748                                         { //free the old instance(s)
01749                                                 trap_G2API_CleanGhoul2Models(&oldG2Weapons[j]);
01750                                                 oldG2Weapons[j] = 0;
01751                                         }
01752                                 }
01753 
01754                                 cg_entities[clientNum].weapon = 0;
01755                                 cg_entities[clientNum].ghoul2weapon = NULL; //force a refresh
01756                         }
01757                         j++;
01758                 }
01759         }
01760 
01761         //Check for any sabers that didn't get set again, if they didn't, then reassign the pointers for the new ci
01762         k = 0;
01763         while (k < MAX_SABERS)
01764         {
01765                 if (oldG2Weapons[k])
01766                 {
01767                         newInfo.ghoul2Weapons[k] = oldG2Weapons[k];
01768                 }
01769                 k++;
01770         }
01771 
01772         //duel team
01773         v = Info_ValueForKey( configstring, "dt" );
01774 
01775         if (v)
01776         {
01777                 newInfo.duelTeam = atoi(v);
01778         }
01779         else
01780         {
01781                 newInfo.duelTeam = 0;
01782         }
01783 
01784         // force powers
01785         v = Info_ValueForKey( configstring, "forcepowers" );
01786         Q_strncpyz( newInfo.forcePowers, v, sizeof( newInfo.forcePowers ) );
01787 
01788         if (cgs.gametype >= GT_TEAM     && !cgs.jediVmerc && cgs.gametype != GT_SIEGE )
01789         { //We won't force colors for siege.
01790                 BG_ValidateSkinForTeam( newInfo.modelName, newInfo.skinName, newInfo.team, newInfo.colorOverride );
01791         }
01792         else
01793         {
01794                 newInfo.colorOverride[0] = newInfo.colorOverride[1] = newInfo.colorOverride[2] = 0.0f;
01795         }
01796 
01797         // scan for an existing clientinfo that matches this modelname
01798         // so we can avoid loading checks if possible
01799         if ( !CG_ScanForExistingClientInfo( &newInfo, clientNum ) ) {
01800                 // if we are defering loads, just have it pick the first valid
01801                 if (cg.snap && cg.snap->ps.clientNum == clientNum)
01802                 { //rww - don't defer your own client info ever
01803                         CG_LoadClientInfo( &newInfo );
01804                 }
01805                 else if (  cg_deferPlayers.integer && cgs.gametype != GT_SIEGE && !cg_buildScript.integer && !cg.loading ) {
01806                         // keep whatever they had if it won't violate team skins
01807                         CG_SetDeferredClientInfo( &newInfo );
01808                 } else {
01809                         CG_LoadClientInfo( &newInfo );
01810                 }
01811         }
01812 
01813         // replace whatever was there with the new one
01814         newInfo.infoValid = qtrue;
01815         if (ci->ghoul2Model &&
01816                 ci->ghoul2Model != newInfo.ghoul2Model &&
01817                 trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
01818         { //We must kill this instance before we remove our only pointer to it from the cgame.
01819           //Otherwise we will end up with extra instances all over the place, I think.
01820                 trap_G2API_CleanGhoul2Models(&ci->ghoul2Model);
01821         }
01822         *ci = newInfo;
01823 
01824         //force a weapon change anyway, for all clients being rendered to the current client
01825         while (i < MAX_CLIENTS)
01826         {
01827                 cg_entities[i].ghoul2weapon = NULL;
01828                 i++;
01829         }
01830 
01831         if (clientNum != -1)
01832         { //don't want it using an invalid pointer to share
01833                 trap_G2API_ClearAttachedInstance(clientNum);
01834         }
01835 
01836         // Check if the ghoul2 model changed in any way.  This is safer than assuming we have a legal cent shile loading info.
01837         if (entitiesInitialized && ci->ghoul2Model && (oldGhoul2 != ci->ghoul2Model))
01838         {       // Copy the new ghoul2 model to the centity.
01839                 animation_t *anim;
01840                 centity_t *cent = &cg_entities[clientNum];
01841                 
01842                 anim = &bgHumanoidAnimations[ (cg_entities[clientNum].currentState.legsAnim) ];
01843 
01844                 if (anim)
01845                 {
01846                         int flags = BONE_ANIM_OVERRIDE_FREEZE;
01847                         int firstFrame = anim->firstFrame;
01848                         int setFrame = -1;
01849                         float animSpeed = 50.0f / anim->frameLerp;
01850 
01851                         if (anim->loopFrames != -1)
01852                         {
01853                                 flags = BONE_ANIM_OVERRIDE_LOOP;
01854                         }
01855 
01856                         if (cent->pe.legs.frame >= anim->firstFrame && cent->pe.legs.frame <= (anim->firstFrame + anim->numFrames))
01857                         {
01858                                 setFrame = cent->pe.legs.frame;
01859                         }
01860 
01861                         //rww - Set the animation again because it just got reset due to the model change
01862                         trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "model_root", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
01863 
01864                         cg_entities[clientNum].currentState.legsAnim = 0;
01865                 }
01866 
01867                 anim = &bgHumanoidAnimations[ (cg_entities[clientNum].currentState.torsoAnim) ];
01868 
01869                 if (anim)
01870                 {
01871                         int flags = BONE_ANIM_OVERRIDE_FREEZE;
01872                         int firstFrame = anim->firstFrame;
01873                         int setFrame = -1;
01874                         float animSpeed = 50.0f / anim->frameLerp;
01875 
01876                         if (anim->loopFrames != -1)
01877                         {
01878                                 flags = BONE_ANIM_OVERRIDE_LOOP;
01879                         }
01880 
01881                         if (cent->pe.torso.frame >= anim->firstFrame && cent->pe.torso.frame <= (anim->firstFrame + anim->numFrames))
01882                         {
01883                                 setFrame = cent->pe.torso.frame;
01884                         }
01885 
01886                         //rww - Set the animation again because it just got reset due to the model change
01887                         trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "lower_lumbar", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
01888 
01889                         cg_entities[clientNum].currentState.torsoAnim = 0;
01890                 }
01891 
01892                 if (cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2))
01893                 {
01894                         trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2);
01895                 }
01896                 trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2);
01897 
01898                 if (clientNum != -1)
01899                 {
01900                         //Attach the instance to this entity num so we can make use of client-server
01901                         //shared operations if possible.
01902                         trap_G2API_AttachInstanceToEntNum(cg_entities[clientNum].ghoul2, clientNum, qfalse);
01903                 }
01904 
01905                 if (trap_G2API_AddBolt(cg_entities[clientNum].ghoul2, 0, "face") == -1)
01906                 { //check now to see if we have this bone for setting anims and such
01907                         cg_entities[clientNum].noFace = qtrue;
01908                 }
01909 
01910                 cg_entities[clientNum].localAnimIndex = CG_G2SkelForModel(cg_entities[clientNum].ghoul2);
01911                 cg_entities[clientNum].eventAnimIndex = CG_G2EvIndexForModel(cg_entities[clientNum].ghoul2, cg_entities[clientNum].localAnimIndex);
01912 
01913                 if (cg_entities[clientNum].currentState.number != cg.predictedPlayerState.clientNum &&
01914                         cg_entities[clientNum].currentState.weapon == WP_SABER)
01915                 {
01916                         cg_entities[clientNum].weapon = cg_entities[clientNum].currentState.weapon;
01917                         if (cg_entities[clientNum].ghoul2 && ci->ghoul2Model)
01918                         {
01919                                 CG_CopyG2WeaponInstance(&cg_entities[clientNum], cg_entities[clientNum].currentState.weapon, cg_entities[clientNum].ghoul2);
01920                                 cg_entities[clientNum].ghoul2weapon = CG_G2WeaponInstance(&cg_entities[clientNum], cg_entities[clientNum].currentState.weapon);
01921                         }
01922                         if (!cg_entities[clientNum].currentState.saberHolstered)
01923                         { //if not holstered set length and desired length for both blades to full right now.
01924                                 int j;
01925                                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
01926                                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
01927 
01928                                 i = 0;
01929                                 while (i < MAX_SABERS)
01930                                 {
01931                                         j = 0;
01932                                         while (j < ci->saber[i].numBlades)
01933                                         {
01934                                                 ci->saber[i].blade[j].length = ci->saber[i].blade[j].lengthMax;
01935                                                 j++;
01936                                         }
01937                                         i++;
01938                                 }
01939                         }
01940                 }
01941         }
01942 }

qboolean CG_ParseSurfsFile const char *  modelName,
const char *  skinName,
char *  surfOff,
char *  surfOn
 

Definition at line 314 of file cg_players.c.

References COM_ParseExt(), COM_ParseString(), Com_Printf(), Com_sprintf(), fileHandle_t, FS_READ, MAX_QPATH, MAX_SURF_LIST_SIZE, memset(), Q_strcat(), Q_stricmp(), Q_strncpyz(), qboolean, qfalse, qtrue, trap_FS_FCloseFile(), trap_FS_FOpenFile(), and trap_FS_Read().

00315 {
00316         const char      *text_p;
00317         int                     len;
00318         const char      *token;
00319         const char      *value;
00320         char            text[20000];
00321         char            sfilename[MAX_QPATH];
00322         fileHandle_t    f;
00323         int                     i = 0;
00324 
00325         while (skinName && skinName[i])
00326         {
00327                 if (skinName[i] == '|')
00328                 { //this is a multi-part skin, said skins do not support .surf files
00329                         return qfalse;
00330                 }
00331 
00332                 i++;
00333         }
00334 
00335 
00336         // Load and parse .surf file
00337         Com_sprintf( sfilename, sizeof( sfilename ), "models/players/%s/model_%s.surf", modelName, skinName );
00338 
00339         // load the file
00340         len = trap_FS_FOpenFile( sfilename, &f, FS_READ );
00341         if ( len <= 0 ) 
00342         {//no file
00343                 return qfalse;
00344         }
00345         if ( len >= sizeof( text ) - 1 ) 
00346         {
00347                 Com_Printf( "File %s too long\n", sfilename );
00348                 return qfalse;
00349         }
00350 
00351         trap_FS_Read( text, len, f );
00352         text[len] = 0;
00353         trap_FS_FCloseFile( f );
00354 
00355         // parse the text
00356         text_p = text;
00357 
00358         memset( (char *)surfOff, 0, sizeof(surfOff) );
00359         memset( (char *)surfOn, 0, sizeof(surfOn) );
00360 
00361         // read information for surfOff and surfOn
00362         while ( 1 ) 
00363         {
00364                 token = COM_ParseExt( &text_p, qtrue );
00365                 if ( !token || !token[0] ) 
00366                 {
00367                         break;
00368                 }
00369 
00370                 // surfOff
00371                 if ( !Q_stricmp( token, "surfOff" ) ) 
00372                 {
00373                         if ( COM_ParseString( &text_p, &value ) ) 
00374                         {
00375                                 continue;
00376                         }
00377                         if ( surfOff && surfOff[0] )
00378                         {
00379                                 Q_strcat( surfOff, MAX_SURF_LIST_SIZE, "," );
00380                                 Q_strcat( surfOff, MAX_SURF_LIST_SIZE, value );
00381                         }
00382                         else
00383                         {
00384                                 Q_strncpyz( surfOff, value, MAX_SURF_LIST_SIZE );
00385                         }
00386                         continue;
00387                 }
00388                 
00389                 // surfOn
00390                 if ( !Q_stricmp( token, "surfOn" ) ) 
00391                 {
00392                         if ( COM_ParseString( &text_p, &value ) ) 
00393                         {
00394                                 continue;
00395                         }
00396                         if ( surfOn && surfOn[0] )
00397                         {
00398                                 Q_strcat( surfOn, MAX_SURF_LIST_SIZE, ",");
00399                                 Q_strcat( surfOn, MAX_SURF_LIST_SIZE, value );
00400                         }
00401                         else
00402                         {
00403                                 Q_strncpyz( surfOn, value, MAX_SURF_LIST_SIZE );
00404                         }
00405                         continue;
00406                 }
00407         }
00408         return qtrue;
00409 }

void CG_Player centity_t cent  ) 
 

Definition at line 8408 of file cg_players.c.

References addspriteArgStruct_s::accel, entityState_s::activeForcePass, addspriteArgStruct_t, refEntity_t::angles, AnglesToAxis(), AngleVectors(), entityState_s::apos, vehicleInfo_t::AttachRiders, refEntity_t::axis, refEntity_t::backlerp, centity_s::beamEnd, BG_AttachToRancor(), BG_EmplacedView(), BG_SI_SetDesiredLength(), BG_SI_SetLength(), BG_SI_SetLengthGradual(), bgEntity_t, saberInfo_t::blade, cgMedia_t::blueSaberGlowShader, centity_s::bodyFadeTime, entityState_s::bolt1, entityState_s::bolt2, centity_s::bolt2, centity_s::bolt3, clientInfo_t::bolt_head, clientInfo_t::bolt_lhand, clientInfo_t::bolt_llumbar, clientInfo_t::bolt_motion, clientInfo_t::bolt_rhand, cgMedia_t::boltShader, BONE_ANIM_OVERRIDE_FREEZE, cgMedia_t::boonShader, BOTH_FORCE_2HANDEDLIGHTNING_HOLD, addspriteArgStruct_s::bounce, BROKENLIMB_LARM, entityState_s::brokenLimbs, centity_t, cg, CG_AddBracketedEnt(), CG_AddPlayerWeapon(), CG_AddRadarEnt(), CG_AddSaberBlade(), cg_auraShell, cg_cameraMode, CG_CheckThirdPersonAlpha(), CG_ConfigString(), CG_CopyG2WeaponInstance(), CG_CreateNPCClient(), CG_Disintegration(), cg_drawFriend, CG_DrawPlayerSphere(), cg_entities, CG_Error(), cg_fpls, CG_G2EvIndexForModel(), cg_g2JetpackInstance, CG_G2PlayerHeadAnims(), CG_G2SkelForModel(), CG_G2WeaponInstance(), CG_InFighter(), CG_IsMindTricked(), CG_ManualEntityRender(), CG_PlayerHitFX(), CG_RadiusForCent(), CG_ReattachLimb(), cg_renderToTextureFX, CG_SetGhoul2Info(), cg_shadows, cg_smoothClients, cg_speedTrail, CG_ThereIsAMaster(), CG_TriggerAnimSounds(), CG_VehicleAttachDroidUnit(), CG_VehicleShouldDrawShields(), cgs, cgSiegeTeam1PlShader, cgSiegeTeam2PlShader, CHAN_AUTO, CLASS_REMOTE, CLASS_SEEKER, CLASS_VEHICLE, cgs_t::clientinfo, playerState_s::clientNum, entityState_s::clientNum, centity_s::cloaked, cgMedia_t::cloakedShader, clientInfo_t::colorOverride, Com_Printf(), cos(), cgMedia_t::crackleSound, CS_MODELS, centity_s::currentState, entityState_s::customRGBA, refEntity_t::customShader, addspriteArgStruct_s::dscale, playerState_s::duelIndex, playerState_s::duelInProgress, clientInfo_t::duelTeam, DUELTEAM_DOUBLE, centity_s::dustTrailTime, addspriteArgStruct_s::eAlpha, EF2_GENERIC_NPC_FLAG, EF2_HELD_BY_MONSTER, EF2_HYPERSPACE, EF2_SHIP_DEATH, EF_BODYPUSH, EF_DEAD, EF_DISINTEGRATION, EF_INVULNERABLE, EF_JETPACK, EF_JETPACK_ACTIVE, EF_JETPACK_FLAMING, EF_NODRAW, EF_RAG, EF_SEEKERDRONE, cgs_t::effects, entityState_s::eFlags, entityState_s::eFlags2, cgMedia_t::electricBody2Shader, cgMedia_t::electricBodyShader, entityState_s::emplacedOwner, cgMedia_t::endarkenmentShader, cgMedia_t::enlightenmentShader, ENTITYNUM_NONE, ENTITYNUM_WORLD, ET_NPC, ET_TERRAIN, entityState_s::eType, centity_s::eventAnimIndex, playerState_s::fd, addspriteArgStruct_s::flags, floor(), FORCE_DARKSIDE, FORCE_LEVEL_2, FORCE_LEVEL_3, FORCE_LIGHTSIDE, cgEffects_t::forceDrain, cgEffects_t::forceDrainWide, forceHolocronModels, cgEffects_t::forceLightning, cgEffects_t::forceLightningWide, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, forcedata_s::forceMindtrickTargetIndex4, forcePowerDarkLight, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, entityState_s::forcePowersActive, cgMedia_t::forceShell, cgMedia_t::forceSightBubble, FP_ABSORB, FP_GRIP, FP_PROTECT, FP_RAGE, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SABERTHROW, FP_SEE, lerpFrame_t::frame, clientInfo_t::frame, refEntity_t::frame, centity_s::frame_hold, centity_s::frame_hold_refreshed, centity_s::frame_hold_time, centity_s::frame_minus1, centity_s::frame_minus1_refreshed, centity_s::frame_minus2, centity_s::frame_minus2_refreshed, cgs_t::gameModels, cgs_t::gametype, entityState_s::genericenemyindex, refEntity_t::ghoul2, centity_s::ghoul2, clientInfo_t::ghoul2Model, centity_s::ghoul2weapon, cgs_t::glconfig, cgMedia_t::greenSaberGlowShader, entityState_s::groundEntityNum, GT_CTY, GT_HOLOCRON, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, GT_TEAM, entityState_s::hasLookTarget, entityState_s::heldByClient, refEntity_t::hModel, entityState_s::iModelScale, clientInfo_t::infoValid, vmCvar_t::integer, cgMedia_t::invulnerabilityShader, entityState_s::isJediMaster, playerState_s::isJediMaster, centity_s::isRagging, bladeInfo_t::length, centity_s::lerpAngles, centity_s::lerpOrigin, addspriteArgStruct_s::life, refEntity_t::lightingOrigin, centity_s::localAnimIndex, entityState_s::lookTarget, entityState_s::m_iVehicleNum, playerState_s::m_iVehicleNum, M_PI, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, centity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, mdxaBone_t::matrix, MAX_CLIENTS, MAX_GENTITIES, MAX_SABERS, cgEffects_t::mBobaJet, cgs_t::media, memcpy(), memset(), cgEffects_t::mForceConfustionOld, centity_s::miscTime, saberInfo_t::model, entityState_s::modelGhoul2, entityState_s::modelindex, refEntity_t::modelScale, centity_s::modelScale, NEGATIVE_Y, centity_s::noFace, centity_s::noLumbar, entityState_s::NPC_class, centity_s::npcClient, NULL, NUM_FORCE_POWERS, entityState_s::number, saberInfo_t::numBlades, refEntity_t::oldframe, refEntity_t::oldorigin, addspriteArgStruct_s::origin, refEntity_t::origin, ORIGIN, playerState_s::origin, entityState_s::otherEntityNum2, entityState_s::owner, centity_s::pe, PERS_TEAM, playerState_s::persistant, PITCH, lerpFrame_t::pitchAngle, cgMedia_t::playerShieldDamage, centity_s::playerState, playerState_s::pm_flags, PM_INTERMISSION, playerState_s::pm_type, PMF_FOLLOW, entityState_s::pos, POSITIVE_X, cgMedia_t::powerDuelAllyShader, entityState_s::powerups, cg_t::predictedPlayerState, cgMedia_t::protectShader, snapshot_t::ps, PW_BLUEFLAG, PW_CLOAKED, PW_DISINT_4, PW_FORCE_BOON, PW_FORCE_ENLIGHTENED_DARK, PW_FORCE_ENLIGHTENED_LIGHT, PW_REDFLAG, PW_SHIELDHIT, PW_SPEED, PW_SPEEDBURST, PW_YSALAMIRI, Q_irand(), qboolean, qfalse, qtrue, refEntity_t::radius, rand(), random, RARMBIT, cgMedia_t::redSaberGlowShader, cg_t::refdef, refEntity_t::renderfx, cg_t::renderingThirdPerson, RF_FORCE_ENT_ALPHA, RF_LIGHTING_ORIGIN, RF_MINLIGHT, RF_NODEPTH, RF_RGB_TINT, RF_SHADOW_ONLY, RF_SHADOW_PLANE, RF_THIRD_PERSON, RHANDBIT, ROLL, addspriteArgStruct_s::rotation, clientInfo_t::saber, entityState_s::saberEntityNum, saberInfo_t::saberFlags, entityState_s::saberHolstered, entityState_s::saberInFlight, centity_s::saberWasInFlight, addspriteArgStruct_s::sAlpha, addspriteArgStruct_s::scale, ScaleModelAxis(), centity_s::serverSaberHitIndex, SFL_RETURN_DAMAGE, addspriteArgStruct_s::shader, refEntity_t::shaderRGBA, refEntity_t::shadowPlane, vehicleInfo_t::shieldShaderHandle, SIEGETEAM_TEAM1, cgMedia_t::sightShell, sin(), cg_t::snap, saberInfo_t::soundLoop, saberInfo_t::soundOff, saberInfo_t::soundOn, SPEED_TRAIL_DISTANCE, glconfig_t::stencilBits, clientInfo_t::superSmoothTime, clientInfo_t::team, TEAM_BLUE, TEAM_FREE, TEAM_RED, TEAM_SPECTATOR, cgMedia_t::teamBlueShader, centity_s::teamPowerEffectTime, centity_s::teamPowerType, cgMedia_t::teamRedShader, cg_t::time, entityState_s::time2, playerEntity_t::torso, entityState_s::torsoAnim, centity_s::torsoBolt, trap_Cvar_Set(), trap_FX_AddSprite(), trap_FX_PlayEffectID(), trap_FX_PlayEntityEffectID(), trap_G2_HaveWeGhoul2Models(), trap_G2API_AbsurdSmoothing(), trap_G2API_AddBolt(), trap_G2API_AttachInstanceToEntNum(), trap_G2API_CleanGhoul2Models(), trap_G2API_ClearAttachedInstance(), trap_G2API_CopySpecificGhoul2Model(), trap_G2API_DuplicateGhoul2Instance(), trap_G2API_GetBoltMatrix(), trap_G2API_HasGhoul2ModelOnIndex(), trap_G2API_InitGhoul2Model(), trap_G2API_RemoveGhoul2Model(), trap_G2API_SetBoneAngles(), trap_G2API_SetBoneAnim(), trap_G2API_SetRagDoll(), trap_R_AddRefEntityToScene(), trap_R_RegisterModel(), trap_R_RegisterShader(), trap_R_SetRefractProp(), trap_S_AddLoopingSound(), trap_S_RegisterSound(), trap_S_StartSound(), trajectory_t::trBase, trajectory_t::trDelta, centity_s::trickAlpha, centity_s::trickAlphaTime, entityState_s::trickedentindex, entityState_s::trickedentindex2, entityState_s::trickedentindex3, entityState_s::trickedentindex4, trajectory_t::trTime, centity_s::turAngles, vehicleInfo_t::type, centity_s::uncloaking, va(), vec3_origin, vec3_t, vec4_t, vectoangles(), VectorAdd, VectorClear, VectorCopy, VectorMA, VectorNormalize(), VectorSet, VectorSubtract, Vehicle_t, addspriteArgStruct_s::vel, VH_FIGHTER, playerState_s::viewangles, refdef_t::vieworg, WAISTBIT, centity_s::weapon, entityState_s::weapon, WP_EMPLACED_GUN, WP_SABER, WP_STUN_BATON, YAW, lerpFrame_t::yawAngle, cgMedia_t::yellowDroppedSaberShader, cgMedia_t::ysaliblueShader, cgMedia_t::ysalimariShader, and cgMedia_t::ysaliredShader.

Referenced by CG_G2Animated().

08408                                   {
08409         clientInfo_t    *ci;
08410         refEntity_t             legs;
08411         refEntity_t             torso;
08412         int                             clientNum;
08413         int                             renderfx;
08414         qboolean                shadow = qfalse;
08415         float                   shadowPlane = 0;
08416         qboolean                dead = qfalse;
08417         vec3_t                  rootAngles;
08418         float                   angle;
08419         vec3_t                  angles, dir, elevated, enang, seekorg;
08420         int                             iwantout = 0, successchange = 0;
08421         int                             team;
08422         mdxaBone_t              boltMatrix, lHandMatrix;
08423         int                             doAlpha = 0;
08424         qboolean                gotLHandMatrix = qfalse;
08425         qboolean                g2HasWeapon = qfalse;
08426         qboolean                drawPlayerSaber = qfalse;
08427         qboolean                checkDroidShields = qfalse;
08428 
08429         //first if we are not an npc and we are using an emplaced gun then make sure our
08430         //angles are visually capped to the constraints (otherwise it's possible to lerp
08431         //a little outside and look kind of twitchy)
08432         if (cent->currentState.weapon == WP_EMPLACED_GUN &&
08433                 cent->currentState.otherEntityNum2)
08434         {
08435                 float empYaw;
08436 
08437                 if (BG_EmplacedView(cent->lerpAngles, cg_entities[cent->currentState.otherEntityNum2].currentState.angles, &empYaw, cg_entities[cent->currentState.otherEntityNum2].currentState.origin2[0]))
08438                 {
08439                         cent->lerpAngles[YAW] = empYaw;
08440                 }
08441         }
08442 
08443         if (cent->currentState.iModelScale)
08444         { //if the server says we have a custom scale then set it now.
08445                 cent->modelScale[0] = cent->modelScale[1] = cent->modelScale[2] = cent->currentState.iModelScale/100.0f;
08446                 if ( cent->currentState.NPC_class != CLASS_VEHICLE )
08447                 {
08448                         if (cent->modelScale[2] && cent->modelScale[2] != 1.0f)
08449                         {
08450                                 cent->lerpOrigin[2] += 24 * (cent->modelScale[2] - 1);
08451                         }
08452                 }
08453         }
08454         else
08455         {
08456                 VectorClear(cent->modelScale);
08457         }
08458 
08459         if ((cg_smoothClients.integer || cent->currentState.heldByClient) && (cent->currentState.groundEntityNum >= ENTITYNUM_WORLD || cent->currentState.eType == ET_TERRAIN) &&
08460                 !(cent->currentState.eFlags2 & EF2_HYPERSPACE) && cg.predictedPlayerState.m_iVehicleNum != cent->currentState.number)
08461         { //always smooth when being thrown
08462                 vec3_t                  posDif;
08463                 float                   smoothFactor;
08464                 int                             k = 0;
08465                 float                   fTolerance = 20000.0f;
08466 
08467                 if (cent->currentState.heldByClient)
08468                 { //smooth the origin more when in this state, because movement is origin-based on server.
08469                         smoothFactor = 0.2f;
08470                 }
08471                 else if ( (cent->currentState.powerups & (1 << PW_SPEED)) ||
08472                         (cent->currentState.forcePowersActive & (1 << FP_RAGE)) )
08473                 { //we're moving fast so don't smooth as much
08474                         smoothFactor = 0.6f;
08475                 }
08476                 else if (cent->currentState.eType == ET_NPC && cent->currentState.NPC_class == CLASS_VEHICLE &&
08477                         cent->m_pVehicle && cent->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER)
08478                 { //greater smoothing for flying vehicles, since they move so fast
08479                         fTolerance = 6000000.0f;//500000.0f; //yeah, this is so wrong..but..
08480                         smoothFactor = 0.5f;
08481                 }
08482                 else
08483                 {
08484                         smoothFactor = 0.5f;
08485                 }
08486                 
08487                 if (DistanceSquared(cent->beamEnd,cent->lerpOrigin) > smoothFactor*fTolerance) //10000
08488                 {
08489                         VectorCopy(cent->lerpOrigin, cent->beamEnd);
08490                 }
08491 
08492                 VectorSubtract(cent->lerpOrigin, cent->beamEnd, posDif);
08493                 
08494                 for (k=0;k<3;k++)
08495                 {
08496                         cent->beamEnd[k]=(cent->beamEnd[k]+posDif[k]*smoothFactor);
08497                         cent->lerpOrigin[k]=cent->beamEnd[k];
08498                 }
08499         }
08500         else
08501         {
08502                 VectorCopy(cent->lerpOrigin, cent->beamEnd);
08503         }
08504 
08505         if (cent->currentState.m_iVehicleNum &&
08506                 cent->currentState.NPC_class != CLASS_VEHICLE)
08507         { //this player is riding a vehicle
08508                 centity_t *veh = &cg_entities[cent->currentState.m_iVehicleNum];
08509 
08510                 cent->lerpAngles[YAW] = veh->lerpAngles[YAW];
08511 
08512                 //Attach ourself to the vehicle
08513         if (veh->m_pVehicle &&
08514                         cent->playerState &&
08515                         veh->playerState &&
08516                         cent->ghoul2 &&
08517                         veh->ghoul2 )
08518                 {
08519                         if ( veh->currentState.owner != cent->currentState.clientNum )
08520                         {//FIXME: what about visible passengers?
08521                                 if ( CG_VehicleAttachDroidUnit( cent, &legs ) )
08522                                 {
08523                                         checkDroidShields = qtrue;
08524                                 }
08525                         }
08526                         else if ( veh->currentState.owner != ENTITYNUM_NONE)
08527                         {//has a pilot...???
08528                                 vec3_t oldPSOrg;
08529 
08530                                 //make sure it has its pilot and parent set
08531                                 veh->m_pVehicle->m_pPilot = (bgEntity_t *)&cg_entities[veh->currentState.owner];
08532                                 veh->m_pVehicle->m_pParentEntity = (bgEntity_t *)veh;
08533                     
08534                                 VectorCopy(veh->playerState->origin, oldPSOrg);
08535 
08536                                 //update the veh's playerstate org for getting the bolt
08537                                 VectorCopy(veh->lerpOrigin, veh->playerState->origin);
08538                                 VectorCopy(cent->lerpOrigin, cent->playerState->origin);
08539 
08540                                 //Now do the attach
08541                                 VectorCopy(veh->lerpAngles, veh->playerState->viewangles);
08542                                 veh->m_pVehicle->m_pVehicleInfo->AttachRiders(veh->m_pVehicle);
08543 
08544                                 //copy the "playerstate origin" to the lerpOrigin since that's what we use to display
08545                                 VectorCopy(cent->playerState->origin, cent->lerpOrigin);
08546 
08547                                 VectorCopy(oldPSOrg, veh->playerState->origin);
08548                         }
08549                 }
08550         }
08551 
08552         // the client number is stored in clientNum.  It can't be derived
08553         // from the entity number, because a single client may have
08554         // multiple corpses on the level using the same clientinfo
08555         if (cent->currentState.eType != ET_NPC)
08556         {
08557                 clientNum = cent->currentState.clientNum;
08558                 if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) {
08559                         CG_Error( "Bad clientNum on player entity");
08560                 }
08561                 ci = &cgs.clientinfo[ clientNum ];
08562         }
08563         else
08564         {
08565                 if (!cent->npcClient)
08566                 {
08567                         CG_CreateNPCClient(&cent->npcClient); //allocate memory for it
08568 
08569                         if (!cent->npcClient)
08570                         {
08571                                 assert(0);
08572                                 return;
08573                         }
08574 
08575                         memset(cent->npcClient, 0, sizeof(clientInfo_t));
08576                         cent->npcClient->ghoul2Model = NULL;
08577                 }
08578 
08579                 assert(cent->npcClient);
08580 
08581                 if (cent->npcClient->ghoul2Model != cent->ghoul2 && cent->ghoul2)
08582                 {
08583                         cent->npcClient->ghoul2Model = cent->ghoul2;
08584                         if (cent->localAnimIndex <= 1)
08585                         {
08586                                 cent->npcClient->bolt_rhand = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*r_hand");
08587                                 cent->npcClient->bolt_lhand = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*l_hand");
08588 
08589                                 //rhand must always be first bolt. lhand always second. Whichever you want the
08590                                 //jetpack bolted to must always be third.
08591                                 trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*chestg");
08592 
08593                                 //claw bolts
08594                                 trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*r_hand_cap_r_arm");
08595                                 trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*l_hand_cap_l_arm");
08596 
08597                                 cent->npcClient->bolt_head = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "*head_top");
08598                                 if (cent->npcClient->bolt_head == -1)
08599                                 {
08600                                         cent->npcClient->bolt_head = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "ceyebrow");
08601                                 }
08602                                 cent->npcClient->bolt_motion = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "Motion");
08603                                 cent->npcClient->bolt_llumbar = trap_G2API_AddBolt(cent->npcClient->ghoul2Model, 0, "lower_lumbar");
08604                         }
08605                         else
08606                         {
08607                                 cent->npcClient->bolt_rhand = -1;
08608                                 cent->npcClient->bolt_lhand = -1;
08609                                 cent->npcClient->bolt_head = -1;
08610                                 cent->npcClient->bolt_motion = -1;
08611                                 cent->npcClient->bolt_llumbar = -1;
08612                         }
08613                         cent->npcClient->team = TEAM_FREE;
08614                         cent->npcClient->infoValid = qtrue;
08615                 }
08616                 ci = cent->npcClient;
08617         }
08618 
08619         // it is possible to see corpses from disconnected players that may
08620         // not have valid clientinfo
08621         if ( !ci->infoValid ) {
08622                 return;
08623         }
08624 
08625         // Add the player to the radar if on the same team and its a team game
08626         if (cgs.gametype >= GT_TEAM)
08627         {
08628                 if ( cent->currentState.eType != ET_NPC &&
08629                         cg.snap->ps.clientNum != cent->currentState.number &&
08630                         ci->team == cg.snap->ps.persistant[PERS_TEAM] )
08631                 {
08632                         CG_AddRadarEnt(cent);
08633                 }
08634         }
08635 
08636         if (cent->currentState.eType == ET_NPC &&
08637                 cent->currentState.NPC_class == CLASS_VEHICLE)
08638         { //add vehicles
08639                 CG_AddRadarEnt(cent);
08640                 if ( CG_InFighter() )
08641                 {//this is a vehicle, bracket it
08642                         if ( cg.predictedPlayerState.m_iVehicleNum != cent->currentState.clientNum )
08643                         {//don't add the vehicle I'm in... :)
08644                                 CG_AddBracketedEnt(cent);
08645                         }
08646                 }
08647 
08648         }
08649 
08650         if (!cent->ghoul2)
08651         { //not ready yet?
08652 #ifdef _DEBUG
08653                 Com_Printf("WARNING: Client %i has a null ghoul2 instance\n", cent->currentState.number);
08654 #endif
08655                 trap_G2API_ClearAttachedInstance(cent->currentState.number);
08656 
08657                 if (ci->ghoul2Model &&
08658                         trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
08659                 {
08660 #ifdef _DEBUG
08661                         Com_Printf("Clientinfo instance was valid, duplicating for cent\n");
08662 #endif
08663                         trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cent->ghoul2);
08664 
08665                         //Attach the instance to this entity num so we can make use of client-server
08666                         //shared operations if possible.
08667                         trap_G2API_AttachInstanceToEntNum(cent->ghoul2, cent->currentState.number, qfalse);
08668 
08669                         if (trap_G2API_AddBolt(cent->ghoul2, 0, "face") == -1)
08670                         { //check now to see if we have this bone for setting anims and such
08671                                 cent->noFace = qtrue;
08672                         }
08673 
08674                         cent->localAnimIndex = CG_G2SkelForModel(cent->ghoul2);
08675                         cent->eventAnimIndex = CG_G2EvIndexForModel(cent->ghoul2, cent->localAnimIndex);
08676                 }
08677                 return;
08678         }
08679 
08680         if (ci->superSmoothTime)
08681         { //do crazy smoothing
08682                 if (ci->superSmoothTime > cg.time)
08683                 { //do it
08684                         trap_G2API_AbsurdSmoothing(cent->ghoul2, qtrue);
08685                 }
08686                 else
08687                 { //turn it off
08688                         ci->superSmoothTime = 0;
08689                         trap_G2API_AbsurdSmoothing(cent->ghoul2, qfalse);
08690                 }
08691         }
08692 
08693         if (cg.predictedPlayerState.pm_type == PM_INTERMISSION)
08694         { //don't show all this shit during intermission
08695                 if ( cent->currentState.eType == ET_NPC
08696                         && cent->currentState.NPC_class != CLASS_VEHICLE )
08697                 {//NPC in intermission
08698                 }
08699                 else
08700                 {//don't render players or vehicles in intermissions, allow other NPCs for scripts
08701                         return;
08702                 }
08703         }
08704 
08705         CG_VehicleEffects(cent);
08706 
08707         if ((cent->currentState.eFlags & EF_JETPACK) && !(cent->currentState.eFlags & EF_DEAD) &&
08708                 cg_g2JetpackInstance)
08709         { //should have a jetpack attached
08710                 //1 is rhand weap, 2 is lhand weap (akimbo sabs), 3 is jetpack
08711                 if (!trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 3))
08712                 {
08713                         trap_G2API_CopySpecificGhoul2Model(cg_g2JetpackInstance, 0, cent->ghoul2, 3); 
08714                 }
08715 
08716                 if (cent->currentState.eFlags & EF_JETPACK_ACTIVE)
08717                 {
08718                         mdxaBone_t mat;
08719                         vec3_t flamePos, flameDir;
08720                         int n = 0;
08721 
08722                         while (n < 2)
08723                         {
08724                                 //Get the position/dir of the flame bolt on the jetpack model bolted to the player
08725                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 3, n, &mat, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
08726                                 BG_GiveMeVectorFromMatrix(&mat, ORIGIN, flamePos);
08727 
08728                                 if (n == 0)
08729                                 {
08730                                         BG_GiveMeVectorFromMatrix(&mat, NEGATIVE_Y, flameDir);
08731                                         VectorMA(flamePos, -9.5f, flameDir, flamePos);
08732                                         BG_GiveMeVectorFromMatrix(&mat, POSITIVE_X, flameDir);
08733                                         VectorMA(flamePos, -13.5f, flameDir, flamePos);
08734                                 }
08735                                 else
08736                                 {
08737                                         BG_GiveMeVectorFromMatrix(&mat, POSITIVE_X, flameDir);
08738                                         VectorMA(flamePos, -9.5f, flameDir, flamePos);
08739                                         BG_GiveMeVectorFromMatrix(&mat, NEGATIVE_Y, flameDir);
08740                                         VectorMA(flamePos, -13.5f, flameDir, flamePos);
08741                                 }
08742 
08743                                 if (cent->currentState.eFlags & EF_JETPACK_FLAMING)
08744                                 { //create effects
08745                                         //FIXME: Just one big effect
08746                                         //Play the effect
08747                                         trap_FX_PlayEffectID(cgs.effects.mBobaJet, flamePos, flameDir, -1, -1);
08748                                         trap_FX_PlayEffectID(cgs.effects.mBobaJet, flamePos, flameDir, -1, -1);
08749 
08750                                         //Keep the jet fire sound looping
08751                                         trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, 
08752                                                 trap_S_RegisterSound( "sound/effects/fire_lp" ) );
08753                                 }
08754                                 else
08755                                 { //just idling
08756                                         //FIXME: Different smaller effect for idle
08757                                         //Play the effect
08758                                         trap_FX_PlayEffectID(cgs.effects.mBobaJet, flamePos, flameDir, -1, -1);
08759                                 }
08760 
08761                                 n++;
08762                         }
08763 
08764                         trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, 
08765                                 trap_S_RegisterSound( "sound/boba/JETHOVER" ) );
08766                 }
08767         }
08768         else if (trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 3))
08769         { //fixme: would be good if this could be done not every frame
08770                 trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 3);
08771         }
08772 
08773         g2HasWeapon = trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1);
08774 
08775         if (!g2HasWeapon)
08776         { //force a redup of the weapon instance onto the client instance
08777                 cent->ghoul2weapon = NULL;
08778                 cent->weapon = 0;
08779         }
08780 
08781         if (cent->torsoBolt && !(cent->currentState.eFlags & EF_DEAD))
08782         { //he's alive and has a limb missing still, reattach it and reset the weapon
08783                 CG_ReattachLimb(cent);
08784         }
08785 
08786         if (cent->isRagging && !(cent->currentState.eFlags & EF_DEAD) && !(cent->currentState.eFlags & EF_RAG))
08787         { //make sure we don't ragdoll ever while alive unless directly told to with eFlags
08788                 cent->isRagging = qfalse;
08789                 trap_G2API_SetRagDoll(cent->ghoul2, NULL); //calling with null parms resets to no ragdoll.
08790         }
08791 
08792         if (cent->ghoul2 && cent->torsoBolt && ((cent->torsoBolt & RARMBIT) || (cent->torsoBolt & RHANDBIT) || (cent->torsoBolt & WAISTBIT)) && g2HasWeapon)
08793         { //kill the weapon if the limb holding it is no longer on the model
08794                 trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
08795                 g2HasWeapon = qfalse;
08796         }
08797 
08798         if (!cent->trickAlphaTime || (cg.time - cent->trickAlphaTime) > 1000)
08799         { //things got out of sync, perhaps a new client is trying to fill in this slot
08800                 cent->trickAlpha = 255;
08801                 cent->trickAlphaTime = cg.time;
08802         }
08803 
08804         if (cent->currentState.eFlags & EF_NODRAW)
08805         { //If nodraw, return here
08806                 return;
08807         }
08808         else if (cent->currentState.eFlags2 & EF2_SHIP_DEATH)
08809         { //died in ship, don't draw, we were "obliterated"
08810                 return;
08811         }
08812 
08813         //If this client has tricked you.
08814         if (CG_IsMindTricked(cent->currentState.trickedentindex,
08815                 cent->currentState.trickedentindex2,
08816                 cent->currentState.trickedentindex3,
08817                 cent->currentState.trickedentindex4,
08818                 cg.snap->ps.clientNum))
08819         {
08820                 if (cent->trickAlpha > 1)
08821                 {
08822                         cent->trickAlpha -= (cg.time - cent->trickAlphaTime)*0.5;
08823                         cent->trickAlphaTime = cg.time;
08824 
08825                         if (cent->trickAlpha < 0)
08826                         {
08827                                 cent->trickAlpha = 0;
08828                         }
08829 
08830                         doAlpha = 1;
08831                 }
08832                 else
08833                 {
08834                         doAlpha = 1;
08835                         cent->trickAlpha = 1;
08836                         cent->trickAlphaTime = cg.time;
08837                         iwantout = 1;
08838                 }
08839         }
08840         else
08841         {
08842                 if (cent->trickAlpha < 255)
08843                 {
08844                         cent->trickAlpha += (cg.time - cent->trickAlphaTime);
08845                         cent->trickAlphaTime = cg.time;
08846 
08847                         if (cent->trickAlpha > 255)
08848                         {
08849                                 cent->trickAlpha = 255;
08850                         }
08851 
08852                         doAlpha = 1;
08853                 }
08854                 else
08855                 {
08856                         cent->trickAlpha = 255;
08857                         cent->trickAlphaTime = cg.time;
08858                 }
08859         }
08860 
08861         // get the player model information
08862         renderfx = 0;
08863         if ( cent->currentState.number == cg.snap->ps.clientNum) {
08864                 if (!cg.renderingThirdPerson) {
08865 #if 0
08866                         if (!cg_fpls.integer || cent->currentState.weapon != WP_SABER)
08867 #else
08868                         if (cent->currentState.weapon != WP_SABER)
08869 #endif
08870                         {
08871                                 renderfx = RF_THIRD_PERSON;                     // only draw in mirrors
08872                         }
08873                 } else {
08874                         if (cg_cameraMode.integer) {
08875                                 iwantout = 1;
08876 
08877                                 
08878                                 // goto minimal_add;
08879                                 
08880                                 // NOTENOTE Temporary
08881                                 return;
08882                         }
08883                 }
08884         }
08885 
08886         // Update the player's client entity information regarding weapons.
08887         // Explanation:  The entitystate has a weapond defined on it.  The cliententity does as well.
08888         // The cliententity's weapon tells us what the ghoul2 instance on the cliententity has bolted to it.
08889         // If the entitystate and cliententity weapons differ, then the state's needs to be copied to the client.
08890         // Save the old weapon, to verify that it is or is not the same as the new weapon.
08891         // rww - Make sure weapons don't get set BEFORE cent->ghoul2 is initialized or else we'll have no
08892         // weapon bolted on
08893         if (cent->currentState.saberInFlight)
08894         {
08895                 cent->ghoul2weapon = CG_G2WeaponInstance(cent, WP_SABER);
08896         }
08897 
08898         if (cent->ghoul2 && 
08899                 (cent->currentState.eType != ET_NPC || (cent->currentState.NPC_class != CLASS_VEHICLE&&cent->currentState.NPC_class != CLASS_REMOTE&&cent->currentState.NPC_class != CLASS_SEEKER)) && //don't add weapon models to NPCs that have no bolt for them!
08900                 cent->ghoul2weapon != CG_G2WeaponInstance(cent, cent->currentState.weapon) &&
08901                 !(cent->currentState.eFlags & EF_DEAD) && !cent->torsoBolt &&
08902                 cg.snap && (cent->currentState.number != cg.snap->ps.clientNum || (cg.snap->ps.pm_flags & PMF_FOLLOW)))
08903         {
08904                 if (ci->team == TEAM_SPECTATOR)
08905                 {
08906                         cent->ghoul2weapon = NULL;
08907                         cent->weapon = 0;
08908                 }
08909                 else
08910                 {
08911                         CG_CopyG2WeaponInstance(cent, cent->currentState.weapon, cent->ghoul2);
08912 
08913                         if (cent->currentState.eType != ET_NPC)
08914                         {
08915                                 if (cent->weapon == WP_SABER 
08916                                         && cent->weapon != cent->currentState.weapon 
08917                                         && !cent->currentState.saberHolstered)
08918                                 { //switching away from the saber
08919                                         //trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( "sound/weapons/saber/saberoffquick.wav" ));
08920                                         if (ci->saber[0].soundOff 
08921                                                 && !cent->currentState.saberHolstered)
08922                                         {
08923                                                 trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, ci->saber[0].soundOff);
08924                                         }
08925 
08926                                         if (ci->saber[1].soundOff &&
08927                                                 ci->saber[1].model[0] &&
08928                                                 !cent->currentState.saberHolstered)
08929                                         {
08930                                                 trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, ci->saber[1].soundOff);
08931                                         }
08932 
08933                                 }
08934                                 else if (cent->currentState.weapon == WP_SABER
08935                                         && cent->weapon != cent->currentState.weapon 
08936                                         && !cent->saberWasInFlight)
08937                                 { //switching to the saber
08938                                         //trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( "sound/weapons/saber/saberon.wav" ));
08939                                         if (ci->saber[0].soundOn)
08940                                         {
08941                                                 trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, ci->saber[0].soundOn);
08942                                         }
08943 
08944                                         if (ci->saber[1].soundOn)
08945                                         {
08946                                                 trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_AUTO, ci->saber[1].soundOn);
08947                                         }
08948 
08949                                         BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
08950                                         BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
08951                                 }
08952                         }
08953 
08954                         cent->weapon = cent->currentState.weapon;
08955                         cent->ghoul2weapon = CG_G2WeaponInstance(cent, cent->currentState.weapon);
08956                 }
08957         }
08958         else if ((cent->currentState.eFlags & EF_DEAD) || cent->torsoBolt)
08959         {
08960                 cent->ghoul2weapon = NULL; //be sure to update after respawning/getting limb regrown
08961         }
08962 
08963         
08964         if (cent->saberWasInFlight && g2HasWeapon)
08965         {
08966                  cent->saberWasInFlight = qfalse;
08967         }
08968 
08969         memset (&legs, 0, sizeof(legs));
08970 
08971         CG_SetGhoul2Info(&legs, cent);
08972 
08973         VectorCopy(cent->modelScale, legs.modelScale);
08974         legs.radius = CG_RadiusForCent( cent );
08975         VectorClear(legs.angles);
08976 
08977         if (ci->colorOverride[0] != 0.0f ||
08978                 ci->colorOverride[1] != 0.0f ||
08979                 ci->colorOverride[2] != 0.0f)
08980         {
08981                 legs.shaderRGBA[0] = ci->colorOverride[0]*255.0f;
08982                 legs.shaderRGBA[1] = ci->colorOverride[1]*255.0f;
08983                 legs.shaderRGBA[2] = ci->colorOverride[2]*255.0f;
08984                 legs.shaderRGBA[3] = cent->currentState.customRGBA[3];
08985         }
08986         else
08987         {
08988                 legs.shaderRGBA[0] = cent->currentState.customRGBA[0];
08989                 legs.shaderRGBA[1] = cent->currentState.customRGBA[1];
08990                 legs.shaderRGBA[2] = cent->currentState.customRGBA[2];
08991                 legs.shaderRGBA[3] = cent->currentState.customRGBA[3];
08992         }
08993 
08994 // minimal_add:
08995 
08996         team = ci->team;
08997 
08998         if (cgs.gametype >= GT_TEAM && cg_drawFriend.integer &&
08999                 cent->currentState.number != cg.snap->ps.clientNum &&
09000                 cent->currentState.eType != ET_NPC)
09001         {       // If the view is either a spectator or on the same team as this character, show a symbol above their head.
09002                 if ((cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cg.snap->ps.persistant[PERS_TEAM] == team) &&
09003                         !(cent->currentState.eFlags & EF_DEAD))
09004                 {
09005                         if (cgs.gametype == GT_SIEGE)
09006                         { //check for per-map team shaders
09007                                 if (team == SIEGETEAM_TEAM1)
09008                                 {
09009                                         if (cgSiegeTeam1PlShader)
09010                                         {
09011                                                 CG_PlayerFloatSprite( cent, cgSiegeTeam1PlShader);
09012                                         }
09013                                         else
09014                                         { //if there isn't one fallback to default
09015                                                 CG_PlayerFloatSprite( cent, cgs.media.teamRedShader);
09016                                         }
09017                                 }
09018                                 else
09019                                 {
09020                                         if (cgSiegeTeam2PlShader)
09021                                         {
09022                                                 CG_PlayerFloatSprite( cent, cgSiegeTeam2PlShader);
09023                                         }
09024                                         else
09025                                         { //if there isn't one fallback to default
09026                                                 CG_PlayerFloatSprite( cent, cgs.media.teamBlueShader);
09027                                         }
09028                                 }
09029                         }
09030                         else
09031                         { //generic teamplay
09032                                 if (team == TEAM_RED)
09033                                 {
09034                                         CG_PlayerFloatSprite( cent, cgs.media.teamRedShader);
09035                                 }
09036                                 else    // if (team == TEAM_BLUE)
09037                                 {
09038                                         CG_PlayerFloatSprite( cent, cgs.media.teamBlueShader);
09039                                 }
09040                         }
09041                 }
09042         }
09043         else if (cgs.gametype == GT_POWERDUEL && cg_drawFriend.integer &&
09044                 cent->currentState.number != cg.snap->ps.clientNum)
09045         {
09046                 if (cg.predictedPlayerState.persistant[PERS_TEAM] != TEAM_SPECTATOR &&
09047                         cent->currentState.number < MAX_CLIENTS &&
09048                         !(cent->currentState.eFlags & EF_DEAD) &&
09049                         ci &&
09050                         cgs.clientinfo[cg.snap->ps.clientNum].duelTeam == ci->duelTeam)
09051                 { //ally in powerduel, so draw the icon
09052                         CG_PlayerFloatSprite( cent, cgs.media.powerDuelAllyShader);
09053                 }
09054                 else if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_SPECTATOR &&
09055                         cent->currentState.number < MAX_CLIENTS &&
09056                         !(cent->currentState.eFlags & EF_DEAD) &&
09057                         ci->duelTeam == DUELTEAM_DOUBLE)
09058                 {
09059                         CG_PlayerFloatSprite( cent, cgs.media.powerDuelAllyShader);
09060                 }
09061         }
09062 
09063         if (cgs.gametype == GT_JEDIMASTER && cg_drawFriend.integer &&
09064                 cent->currentState.number != cg.snap->ps.clientNum)                     // Don't show a sprite above a player's own head in 3rd person.
09065         {       // If the view is either a spectator or on the same team as this character, show a symbol above their head.
09066                 if ((cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR || cg.snap->ps.persistant[PERS_TEAM] == team) &&
09067                         !(cent->currentState.eFlags & EF_DEAD))
09068                 {
09069                         if (CG_ThereIsAMaster())
09070                         {
09071                                 if (!cg.snap->ps.isJediMaster)
09072                                 {
09073                                         if (!cent->currentState.isJediMaster)
09074                                         {
09075                                                 CG_PlayerFloatSprite( cent, cgs.media.teamRedShader);
09076                                         }
09077                                 }
09078                         }
09079                 }
09080         }
09081 
09082         // add the shadow
09083         shadow = CG_PlayerShadow( cent, &shadowPlane );
09084 
09085         if ( ((cent->currentState.eFlags & EF_SEEKERDRONE) || cent->currentState.genericenemyindex != -1) && cent->currentState.eType != ET_NPC )
09086         {
09087                 refEntity_t             seeker;
09088 
09089                 memset( &seeker, 0, sizeof(seeker) );
09090 
09091                 VectorCopy(cent->lerpOrigin, elevated);
09092                 elevated[2] += 40;
09093 
09094                 VectorCopy( elevated, seeker.lightingOrigin );
09095                 seeker.shadowPlane = shadowPlane;
09096                 seeker.renderfx = 0; //renderfx;
09097                                                          //don't show in first person?
09098 
09099                 angle = ((cg.time / 12) & 255) * (M_PI * 2) / 255;
09100                 dir[0] = cos(angle) * 20;
09101                 dir[1] = sin(angle) * 20;
09102                 dir[2] = cos(angle) * 5;
09103                 VectorAdd(elevated, dir, seeker.origin);
09104 
09105                 VectorCopy(seeker.origin, seekorg);
09106 
09107                 if (cent->currentState.genericenemyindex > MAX_GENTITIES)
09108                 {
09109                         float prefig = (cent->currentState.genericenemyindex-cg.time)/80;
09110 
09111                         if (prefig > 55)
09112                         {
09113                                 prefig = 55;
09114                         }
09115                         else if (prefig < 1)
09116                         {
09117                                 prefig = 1;
09118                         }
09119 
09120                         elevated[2] -= 55-prefig;
09121 
09122                         angle = ((cg.time / 12) & 255) * (M_PI * 2) / 255;
09123                         dir[0] = cos(angle) * 20;
09124                         dir[1] = sin(angle) * 20;
09125                         dir[2] = cos(angle) * 5;
09126                         VectorAdd(elevated, dir, seeker.origin);
09127                 }
09128                 else if (cent->currentState.genericenemyindex != ENTITYNUM_NONE && cent->currentState.genericenemyindex != -1)
09129                 {
09130                         centity_t *enent = &cg_entities[cent->currentState.genericenemyindex];
09131 
09132                         if (enent)
09133                         {
09134                                 VectorSubtract(enent->lerpOrigin, seekorg, enang);
09135                                 VectorNormalize(enang);
09136                                 vectoangles(enang, angles);
09137                                 successchange = 1;
09138                         }
09139                 }
09140 
09141                 if (!successchange)
09142                 {
09143                         angles[0] = sin(angle) * 30;
09144                         angles[1] = (angle * 180 / M_PI) + 90;
09145                         if (angles[1] > 360)
09146                                 angles[1] -= 360;
09147                         angles[2] = 0;
09148                 }
09149 
09150                 AnglesToAxis( angles, seeker.axis );
09151 
09152                 seeker.hModel = trap_R_RegisterModel("models/items/remote.md3");
09153                 trap_R_AddRefEntityToScene( &seeker );
09154         }
09155 
09156         // add a water splash if partially in and out of water
09157         CG_PlayerSplash( cent );
09158 
09159         if ( (cg_shadows.integer == 3 || cg_shadows.integer == 2) && shadow ) {
09160                 renderfx |= RF_SHADOW_PLANE;
09161         }
09162         renderfx |= RF_LIGHTING_ORIGIN;                 // use the same origin for all
09163 
09164         // if we've been hit, display proper fullscreen fx
09165         CG_PlayerHitFX(cent);
09166 
09167         VectorCopy( cent->lerpOrigin, legs.origin );
09168 
09169         VectorCopy( cent->lerpOrigin, legs.lightingOrigin );
09170         legs.shadowPlane = shadowPlane;
09171         legs.renderfx = renderfx;
09172         if (cg_shadows.integer == 2 && (renderfx & RF_THIRD_PERSON))
09173         { //can see own shadow
09174                 legs.renderfx |= RF_SHADOW_ONLY;
09175         }
09176         VectorCopy (legs.origin, legs.oldorigin);       // don't positionally lerp at all
09177 
09178         CG_G2PlayerAngles( cent, legs.axis, rootAngles );
09179         CG_G2PlayerHeadAnims( cent );
09180 
09181         if ( (cent->currentState.eFlags2&EF2_HELD_BY_MONSTER) 
09182                 && cent->currentState.hasLookTarget )//NOTE: lookTarget is an entity number, so this presumes that client 0 is NOT a Rancor...
09183         {
09184                 centity_t       *rancor = &cg_entities[cent->currentState.lookTarget];
09185                 if ( rancor )
09186                 {
09187                         BG_AttachToRancor( rancor->ghoul2, //ghoul2 info
09188                                 rancor->lerpAngles[YAW],
09189                                 rancor->lerpOrigin,
09190                                 cg.time,
09191                                 cgs.gameModels,
09192                                 rancor->modelScale,
09193                                 (rancor->currentState.eFlags2&EF2_GENERIC_NPC_FLAG),
09194                                 legs.origin,
09195                                 legs.angles,
09196                                 NULL );
09197 
09198                         if ( cent->isRagging )
09199                         {//hack, ragdoll has you way at bottom of bounding box
09200                                 VectorMA( legs.origin, 32, legs.axis[2], legs.origin );
09201                         }
09202                         VectorCopy( legs.origin, legs.oldorigin );
09203                         VectorCopy( legs.origin, legs.lightingOrigin );
09204 
09205                         VectorCopy( legs.angles, cent->lerpAngles );
09206                         VectorCopy( cent->lerpAngles, rootAngles );//??? tempAngles );//tempAngles is needed a lot below
09207                         VectorCopy( cent->lerpAngles, cent->turAngles );
09208                         VectorCopy( legs.origin, cent->lerpOrigin );
09209                 }
09210         }
09211         //This call is mainly just to reconstruct the skeleton. But we'll get the left hand matrix while we're at it.
09212         //If we don't reconstruct the skeleton after setting the bone angles, we will get bad bolt points on the model
09213         //(e.g. the weapon model bolt will look "lagged") if there's no other GetBoltMatrix call for the rest of the
09214         //frame. Yes, this is stupid and needs to be fixed properly.
09215         //The current solution is to force it not to reconstruct the skeleton for the first GBM call in G2PlayerAngles.
09216         //It works and we end up only reconstructing it once, but it doesn't seem like the best solution.
09217         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &lHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09218         gotLHandMatrix = qtrue;
09219 #if 0
09220         if (cg.renderingThirdPerson)
09221         {
09222                 if (cgFPLSState != 0)
09223                 {
09224                         CG_ForceFPLSPlayerModel(cent, ci);
09225                         cgFPLSState = 0;
09226                         return;
09227                 }
09228         }
09229         else if (ci->team == TEAM_SPECTATOR || (cg.snap && (cg.snap->ps.pm_flags & PMF_FOLLOW)))
09230         { //don't allow this when spectating
09231                 if (cgFPLSState != 0)
09232                 {
09233                         trap_Cvar_Set("cg_fpls", "0");
09234                         cg_fpls.integer = 0;
09235 
09236                         CG_ForceFPLSPlayerModel(cent, ci);
09237                         cgFPLSState = 0;
09238                         return;
09239                 }
09240 
09241                 if (cg_fpls.integer)
09242                 {
09243                         trap_Cvar_Set("cg_fpls", "0");
09244                 }
09245         }
09246         else
09247         {
09248                 if (cg_fpls.integer && cent->currentState.weapon == WP_SABER && cg.snap && cent->currentState.number == cg.snap->ps.clientNum)
09249                 {
09250 
09251                         if (cgFPLSState != cg_fpls.integer)
09252                         {
09253                                 CG_ForceFPLSPlayerModel(cent, ci);
09254                                 cgFPLSState = cg_fpls.integer;
09255                                 return;
09256                         }
09257 
09258                         /*
09259                         mdxaBone_t              headMatrix;
09260                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_head, &headMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09261                         BG_GiveMeVectorFromMatrix(&headMatrix, ORIGIN, cg.refdef.vieworg);
09262                         */
09263                 }
09264                 else if (!cg_fpls.integer && cgFPLSState)
09265                 {
09266                         if (cgFPLSState != cg_fpls.integer)
09267                         {
09268                                 CG_ForceFPLSPlayerModel(cent, ci);
09269                                 cgFPLSState = cg_fpls.integer;
09270                                 return;
09271                         }
09272                 }
09273         }
09274 #endif
09275 
09276         if (cent->currentState.eFlags & EF_DEAD)
09277         {
09278                 dead = qtrue;
09279                 //rww - since our angles are fixed when we're dead this shouldn't be an issue anyway
09280                 //we need to render the dying/dead player because we are now spawning the body on respawn instead of death
09281                 //return;
09282         }
09283 
09284         ScaleModelAxis(&legs);
09285 
09286         memset( &torso, 0, sizeof(torso) );
09287 
09288         //rww - force speed "trail" effect
09289         if (!(cent->currentState.powerups & (1 << PW_SPEED)) || doAlpha || !cg_speedTrail.integer)
09290         {
09291                 cent->frame_minus1_refreshed = 0;
09292                 cent->frame_minus2_refreshed = 0;
09293         }
09294 
09295         if (cent->frame_minus1_refreshed ||
09296                 cent->frame_minus2_refreshed)
09297         {
09298                 vec3_t                  tDir;
09299                 int                             distVelBase;
09300 
09301                 VectorCopy(cent->currentState.pos.trDelta, tDir);
09302                 distVelBase = SPEED_TRAIL_DISTANCE*(VectorNormalize(tDir)*0.004);
09303 
09304                 if (cent->frame_minus1_refreshed)
09305                 {
09306                         refEntity_t reframe_minus1 = legs;
09307                         reframe_minus1.renderfx |= RF_FORCE_ENT_ALPHA;
09308                         reframe_minus1.shaderRGBA[0] = legs.shaderRGBA[0];
09309                         reframe_minus1.shaderRGBA[1] = legs.shaderRGBA[1];
09310                         reframe_minus1.shaderRGBA[2] = legs.shaderRGBA[2];
09311                         reframe_minus1.shaderRGBA[3] = 100;
09312 
09313                         //rww - if the client gets a bad framerate we will only receive frame positions
09314                         //once per frame anyway, so we might end up with speed trails very spread out.
09315                         //in order to avoid that, we'll get the direction of the last trail from the player
09316                         //and place the trail refent a set distance from the player location this frame
09317                         VectorSubtract(cent->frame_minus1, legs.origin, tDir);
09318                         VectorNormalize(tDir);
09319 
09320                         cent->frame_minus1[0] = legs.origin[0]+tDir[0]*distVelBase;
09321                         cent->frame_minus1[1] = legs.origin[1]+tDir[1]*distVelBase;
09322                         cent->frame_minus1[2] = legs.origin[2]+tDir[2]*distVelBase;
09323 
09324                         VectorCopy(cent->frame_minus1, reframe_minus1.origin);
09325 
09326                         //reframe_minus1.customShader = 2;
09327 
09328                         trap_R_AddRefEntityToScene(&reframe_minus1);
09329                 }
09330 
09331                 if (cent->frame_minus2_refreshed)
09332                 {
09333                         refEntity_t reframe_minus2 = legs;
09334 
09335                         reframe_minus2.renderfx |= RF_FORCE_ENT_ALPHA;
09336                         reframe_minus2.shaderRGBA[0] = legs.shaderRGBA[0];
09337                         reframe_minus2.shaderRGBA[1] = legs.shaderRGBA[1];
09338                         reframe_minus2.shaderRGBA[2] = legs.shaderRGBA[2];
09339                         reframe_minus2.shaderRGBA[3] = 50;
09340 
09341                         //Same as above but do it between trail points instead of the player and first trail entry
09342                         VectorSubtract(cent->frame_minus2, cent->frame_minus1, tDir);
09343                         VectorNormalize(tDir);
09344 
09345                         cent->frame_minus2[0] = cent->frame_minus1[0]+tDir[0]*distVelBase;
09346                         cent->frame_minus2[1] = cent->frame_minus1[1]+tDir[1]*distVelBase;
09347                         cent->frame_minus2[2] = cent->frame_minus1[2]+tDir[2]*distVelBase;
09348 
09349                         VectorCopy(cent->frame_minus2, reframe_minus2.origin);
09350 
09351                         //reframe_minus2.customShader = 2;
09352 
09353                         trap_R_AddRefEntityToScene(&reframe_minus2);
09354                 }
09355         }
09356 
09357         //trigger animation-based sounds, done before next lerp frame.
09358         CG_TriggerAnimSounds(cent);
09359 
09360         // get the animation state (after rotation, to allow feet shuffle)
09361         CG_PlayerAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp,
09362                  &torso.oldframe, &torso.frame, &torso.backlerp );
09363 
09364         // add the talk baloon or disconnect icon
09365         CG_PlayerSprites( cent );
09366 
09367         if (cent->currentState.eFlags & EF_DEAD)
09368         { //keep track of death anim frame for when we copy off the bodyqueue
09369                 ci->frame = cent->pe.torso.frame;
09370         }
09371 
09372         if (cent->currentState.activeForcePass > FORCE_LEVEL_3
09373                 && cent->currentState.NPC_class != CLASS_VEHICLE)
09374         {
09375                 vec3_t axis[3];
09376                 vec3_t tAng, fAng, fxDir;
09377                 vec3_t efOrg;
09378 
09379                 int realForceLev = (cent->currentState.activeForcePass - FORCE_LEVEL_3);
09380 
09381                 VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
09382 
09383                 VectorSet( fAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
09384 
09385                 AngleVectors( fAng, fxDir, NULL, NULL );
09386 
09387                 if ( cent->currentState.torsoAnim == BOTH_FORCE_2HANDEDLIGHTNING_HOLD 
09388                         && Q_irand( 0, 1 ) )
09389                 {//alternate back and forth between left and right
09390                         mdxaBone_t      rHandMatrix;
09391                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_rhand, &rHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09392                         efOrg[0] = rHandMatrix.matrix[0][3];
09393                         efOrg[1] = rHandMatrix.matrix[1][3];
09394                         efOrg[2] = rHandMatrix.matrix[2][3];
09395                 }
09396                 else
09397                 {
09398                         //trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09399                         if (!gotLHandMatrix)
09400                         {
09401                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &lHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09402                                 gotLHandMatrix = qtrue;
09403                         }
09404                         efOrg[0] = lHandMatrix.matrix[0][3];
09405                         efOrg[1] = lHandMatrix.matrix[1][3];
09406                         efOrg[2] = lHandMatrix.matrix[2][3];
09407                 }
09408 
09409                 AnglesToAxis( fAng, axis );
09410         
09411                 if ( realForceLev > FORCE_LEVEL_2 )
09412                 {//arc
09413                         //trap_FX_PlayEffectID( cgs.effects.forceLightningWide, efOrg, fxDir );
09414                         //trap_FX_PlayEntityEffectID(cgs.effects.forceDrainWide, efOrg, axis, cent->boltInfo, cent->currentState.number, -1, -1);
09415                         trap_FX_PlayEntityEffectID(cgs.effects.forceDrainWide, efOrg, axis, -1, -1, -1, -1);
09416                 }
09417                 else
09418                 {//line
09419                         //trap_FX_PlayEffectID( cgs.effects.forceLightning, efOrg, fxDir );
09420                         //trap_FX_PlayEntityEffectID(cgs.effects.forceDrain, efOrg, axis, cent->boltInfo, cent->currentState.number, -1, -1);
09421                         trap_FX_PlayEntityEffectID(cgs.effects.forceDrain, efOrg, axis, -1, -1, -1, -1);
09422                 }
09423 
09424                 /*
09425                 if (cent->bolt4 < cg.time)
09426                 {
09427                         cent->bolt4 = cg.time + 100;
09428                         trap_S_StartSound(NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/force/drain.wav") );
09429                 }
09430                 */
09431         }
09432         else if ( cent->currentState.activeForcePass 
09433                 && cent->currentState.NPC_class != CLASS_VEHICLE)
09434         {//doing the electrocuting
09435                 vec3_t axis[3];
09436                 vec3_t tAng, fAng, fxDir;
09437                 vec3_t efOrg;
09438 
09439                 VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
09440 
09441                 VectorSet( fAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
09442 
09443                 AngleVectors( fAng, fxDir, NULL, NULL );
09444 
09445                 //trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09446                 if (!gotLHandMatrix)
09447                 {
09448                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &lHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09449                         gotLHandMatrix = qtrue;
09450                 }
09451 
09452                 efOrg[0] = lHandMatrix.matrix[0][3];
09453                 efOrg[1] = lHandMatrix.matrix[1][3];
09454                 efOrg[2] = lHandMatrix.matrix[2][3];
09455 
09456                 AnglesToAxis( fAng, axis );
09457         
09458                 if ( cent->currentState.activeForcePass > FORCE_LEVEL_2 )
09459                 {//arc
09460                         //trap_FX_PlayEffectID( cgs.effects.forceLightningWide, efOrg, fxDir );
09461                         //trap_FX_PlayEntityEffectID(cgs.effects.forceLightningWide, efOrg, axis, cent->boltInfo, cent->currentState.number, -1, -1);
09462                         trap_FX_PlayEntityEffectID(cgs.effects.forceLightningWide, efOrg, axis, -1, -1, -1, -1);
09463                 }
09464                 else
09465                 {//line
09466                         //trap_FX_PlayEffectID( cgs.effects.forceLightning, efOrg, fxDir );
09467                         //trap_FX_PlayEntityEffectID(cgs.effects.forceLightning, efOrg, axis, cent->boltInfo, cent->currentState.number, -1, -1);
09468                         trap_FX_PlayEntityEffectID(cgs.effects.forceLightning, efOrg, axis, -1, -1, -1, -1);
09469                 }
09470 
09471                 /*
09472                 if (cent->bolt4 < cg.time)
09473                 {
09474                         cent->bolt4 = cg.time + 100;
09475                         trap_S_StartSound(NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/force/lightning.wav") );
09476                 }
09477                 */
09478         }
09479 
09480         //fullbody push effect
09481         if (cent->currentState.eFlags & EF_BODYPUSH)
09482         {
09483                 CG_ForcePushBodyBlur(cent);
09484         }
09485 
09486         if ( cent->currentState.powerups & (1 << PW_DISINT_4) )
09487         {
09488                 vec3_t tAng;
09489                 vec3_t efOrg;
09490 
09491                 //VectorSet( tAng, 0, cent->pe.torso.yawAngle, 0 );
09492                 VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
09493 
09494                 //trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09495                 if (!gotLHandMatrix)
09496                 {
09497                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_lhand, &lHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09498                         gotLHandMatrix = qtrue;
09499                 }
09500 
09501                 efOrg[0] = lHandMatrix.matrix[0][3];
09502                 efOrg[1] = lHandMatrix.matrix[1][3];
09503                 efOrg[2] = lHandMatrix.matrix[2][3];
09504 
09505                 if ( (cent->currentState.forcePowersActive & (1 << FP_GRIP)) &&
09506                         (cg.renderingThirdPerson || cent->currentState.number != cg.snap->ps.clientNum) )
09507                 {
09508                         vec3_t boltDir;
09509                         vec3_t origBolt;
09510                         VectorCopy(efOrg, origBolt);
09511                         BG_GiveMeVectorFromMatrix( &lHandMatrix, NEGATIVE_Y, boltDir );
09512 
09513                         CG_ForceGripEffect( efOrg );
09514                         CG_ForceGripEffect( efOrg );
09515 
09516                         /*
09517                         //Render a scaled version of the model's hand with a n337 looking shader
09518                         {
09519                                 const char *rotateBone;
09520                                 char *limbName;
09521                                 char *limbCapName;
09522                                 vec3_t armAng;
09523                                 refEntity_t regrip_arm;
09524                                 float wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f;
09525 
09526                                 //rotateBone = "lradius";
09527                                 rotateBone = "lradiusX";
09528                                 limbName = "l_arm";
09529                                 limbCapName = "l_arm_cap_torso";
09530 
09531                                 if (cent->grip_arm && trap_G2_HaveWeGhoul2Models(cent->grip_arm))
09532                                 {
09533                                         trap_G2API_CleanGhoul2Models(&(cent->grip_arm));
09534                                 }
09535 
09536                                 memset( &regrip_arm, 0, sizeof(regrip_arm) );
09537 
09538                                 VectorCopy(origBolt, efOrg);
09539 
09540 
09541                                 //efOrg[2] += 8;
09542                                 efOrg[2] -= 4;
09543 
09544                                 VectorCopy(efOrg, regrip_arm.origin);
09545                                 VectorCopy(regrip_arm.origin, regrip_arm.lightingOrigin);
09546 
09547                                 //VectorCopy(cent->lerpAngles, armAng);
09548                                 VectorAdd(vec3_origin, rootAngles, armAng);
09549                                 //armAng[ROLL] = -90;
09550                                 armAng[ROLL] = 0;
09551                                 armAng[PITCH] = 0;
09552                                 AnglesToAxis(armAng, regrip_arm.axis);
09553                                 
09554                                 trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, &cent->grip_arm);
09555 
09556                                 //remove all other models
09557                                 if (trap_G2API_HasGhoul2ModelOnIndex(&(cent->grip_arm), 1))
09558                                 { //weapon right
09559                                         trap_G2API_RemoveGhoul2Model(&(cent->grip_arm), 1);
09560                                 }
09561                                 if (trap_G2API_HasGhoul2ModelOnIndex(&(cent->grip_arm), 2))
09562                                 { //weapon left
09563                                         trap_G2API_RemoveGhoul2Model(&(cent->grip_arm), 2);
09564                                 }
09565                                 if (trap_G2API_HasGhoul2ModelOnIndex(&(cent->grip_arm), 3))
09566                                 { //jetpack
09567                                         trap_G2API_RemoveGhoul2Model(&(cent->grip_arm), 3);
09568                                 }
09569 
09570                                 trap_G2API_SetRootSurface(cent->grip_arm, 0, limbName);
09571                                 trap_G2API_SetNewOrigin(cent->grip_arm, trap_G2API_AddBolt(cent->grip_arm, 0, rotateBone));
09572                                 trap_G2API_SetSurfaceOnOff(cent->grip_arm, limbCapName, 0);
09573 
09574                                 regrip_arm.modelScale[0] = 1;//+(wv*6);
09575                                 regrip_arm.modelScale[1] = 1;//+(wv*6);
09576                                 regrip_arm.modelScale[2] = 1;//+(wv*6);
09577                                 ScaleModelAxis(&regrip_arm);
09578 
09579                                 regrip_arm.radius = 64;
09580 
09581                                 regrip_arm.customShader = trap_R_RegisterShader( "gfx/misc/red_portashield" );
09582                                 
09583                                 regrip_arm.renderfx |= RF_RGB_TINT;
09584                                 regrip_arm.shaderRGBA[0] = 255 - (wv*900);
09585                                 if (regrip_arm.shaderRGBA[0] < 30)
09586                                 {
09587                                         regrip_arm.shaderRGBA[0] = 30;
09588                                 }
09589                                 if (regrip_arm.shaderRGBA[0] > 255)
09590                                 {
09591                                         regrip_arm.shaderRGBA[0] = 255;
09592                                 }
09593                                 regrip_arm.shaderRGBA[1] = regrip_arm.shaderRGBA[2] = regrip_arm.shaderRGBA[0];
09594                                 
09595                                 regrip_arm.ghoul2 = cent->grip_arm;
09596                                 trap_R_AddRefEntityToScene( &regrip_arm );
09597                         }
09598                         */
09599                 }
09600                 else if (!(cent->currentState.forcePowersActive & (1 << FP_GRIP)))
09601                 {
09602                         //use refractive effect
09603                         CG_ForcePushBlur( efOrg, cent );
09604                 }
09605         }
09606         else if (cent->bodyFadeTime)
09607         { //reset the counter for keeping track of push refraction effect state
09608                 cent->bodyFadeTime = 0;
09609         }
09610 
09611         if (cent->currentState.weapon == WP_STUN_BATON && cent->currentState.number == cg.snap->ps.clientNum)
09612         {
09613                 trap_S_AddLoopingSound( cent->currentState.number, cg.refdef.vieworg, vec3_origin, 
09614                         trap_S_RegisterSound( "sound/weapons/baton/idle.wav" ) );
09615         }
09616 
09617         //NOTE: All effects that should be visible during mindtrick should go above here
09618 
09619         if (iwantout)
09620         {
09621                 goto stillDoSaber;
09622                 //return;
09623         }
09624         else if (doAlpha)
09625         {
09626                 legs.renderfx |= RF_FORCE_ENT_ALPHA;
09627                 legs.shaderRGBA[3] = cent->trickAlpha;
09628 
09629                 if (legs.shaderRGBA[3] < 1)
09630                 { //don't cancel it out even if it's < 1
09631                         legs.shaderRGBA[3] = 1;
09632                 }
09633         }
09634 
09635         if (cent->teamPowerEffectTime > cg.time)
09636         {
09637                 if (cent->teamPowerType == 3)
09638                 { //absorb is a somewhat different effect entirely
09639                         //Guess I'll take care of it where it's always been, just checking these values instead.
09640                 }
09641                 else
09642                 {
09643                         vec4_t preCol;
09644                         int preRFX;
09645 
09646                         preRFX = legs.renderfx;
09647 
09648                         legs.renderfx |= RF_RGB_TINT;
09649                         legs.renderfx |= RF_FORCE_ENT_ALPHA;
09650 
09651                         preCol[0] = legs.shaderRGBA[0];
09652                         preCol[1] = legs.shaderRGBA[1];
09653                         preCol[2] = legs.shaderRGBA[2];
09654                         preCol[3] = legs.shaderRGBA[3];
09655 
09656                         if (cent->teamPowerType == 1)
09657                         { //heal
09658                                 legs.shaderRGBA[0] = 0;
09659                                 legs.shaderRGBA[1] = 255;
09660                                 legs.shaderRGBA[2] = 0;
09661                         }
09662                         else if (cent->teamPowerType == 0)
09663                         { //regen
09664                                 legs.shaderRGBA[0] = 0;
09665                                 legs.shaderRGBA[1] = 0;
09666                                 legs.shaderRGBA[2] = 255;
09667                         }
09668                         else
09669                         { //drain
09670                                 legs.shaderRGBA[0] = 255;
09671                                 legs.shaderRGBA[1] = 0;
09672                                 legs.shaderRGBA[2] = 0;
09673                         }
09674 
09675                         legs.shaderRGBA[3] = ((cent->teamPowerEffectTime - cg.time)/8);
09676 
09677                         legs.customShader = trap_R_RegisterShader( "powerups/ysalimarishell" );
09678                         trap_R_AddRefEntityToScene(&legs);
09679 
09680                         legs.customShader = 0;
09681                         legs.renderfx = preRFX;
09682                         legs.shaderRGBA[0] = preCol[0];
09683                         legs.shaderRGBA[1] = preCol[1];
09684                         legs.shaderRGBA[2] = preCol[2];
09685                         legs.shaderRGBA[3] = preCol[3];
09686                 }
09687         }
09688 
09689         //If you've tricked this client.
09690         if (CG_IsMindTricked(cg.snap->ps.fd.forceMindtrickTargetIndex,
09691                 cg.snap->ps.fd.forceMindtrickTargetIndex2,
09692                 cg.snap->ps.fd.forceMindtrickTargetIndex3,
09693                 cg.snap->ps.fd.forceMindtrickTargetIndex4,
09694                 cent->currentState.number))
09695         {
09696                 if (cent->ghoul2)
09697                 {
09698                         vec3_t efOrg;
09699                         vec3_t tAng, fxAng;
09700                         vec3_t axis[3];
09701 
09702                         //VectorSet( tAng, 0, cent->pe.torso.yawAngle, 0 );
09703                         VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
09704 
09705                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_head, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
09706 
09707                         BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, efOrg);
09708                         BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_Y, fxAng);
09709 
09710                         axis[0][0] = boltMatrix.matrix[0][0];
09711                         axis[0][1] = boltMatrix.matrix[1][0];
09712                         axis[0][2] = boltMatrix.matrix[2][0];
09713 
09714                         axis[1][0] = boltMatrix.matrix[0][1];
09715                         axis[1][1] = boltMatrix.matrix[1][1];
09716                         axis[1][2] = boltMatrix.matrix[2][1];
09717 
09718                         axis[2][0] = boltMatrix.matrix[0][2];
09719                         axis[2][1] = boltMatrix.matrix[1][2];
09720                         axis[2][2] = boltMatrix.matrix[2][2];
09721 
09722                         //trap_FX_PlayEntityEffectID(trap_FX_RegisterEffect("force/confusion.efx"), efOrg, axis, cent->boltInfo, cent->currentState.number);
09723                         trap_FX_PlayEntityEffectID(cgs.effects.mForceConfustionOld, efOrg, axis, -1, -1, -1, -1);
09724                 }
09725         }
09726 
09727         if (cgs.gametype == GT_HOLOCRON && cent->currentState.time2 && (cg.renderingThirdPerson || cg.snap->ps.clientNum != cent->currentState.number))
09728         {
09729                 int i = 0;
09730                 int renderedHolos = 0;
09731                 refEntity_t             holoRef;
09732 
09733                 while (i < NUM_FORCE_POWERS && renderedHolos < 3)
09734                 {
09735                         if (cent->currentState.time2 & (1 << i))
09736                         {
09737                                 memset( &holoRef, 0, sizeof(holoRef) );
09738 
09739                                 VectorCopy(cent->lerpOrigin, elevated);
09740                                 elevated[2] += 8;
09741 
09742                                 VectorCopy( elevated, holoRef.lightingOrigin );
09743                                 holoRef.shadowPlane = shadowPlane;
09744                                 holoRef.renderfx = 0;//RF_THIRD_PERSON;
09745 
09746                                 if (renderedHolos == 0)
09747                                 {
09748                                         angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255;
09749                                         dir[0] = cos(angle) * 20;
09750                                         dir[1] = sin(angle) * 20;
09751                                         dir[2] = cos(angle) * 20;
09752                                         VectorAdd(elevated, dir, holoRef.origin);
09753 
09754                                         angles[0] = sin(angle) * 30;
09755                                         angles[1] = (angle * 180 / M_PI) + 90;
09756                                         if (angles[1] > 360)
09757                                                 angles[1] -= 360;
09758                                         angles[2] = 0;
09759                                         AnglesToAxis( angles, holoRef.axis );
09760                                 }
09761                                 else if (renderedHolos == 1)
09762                                 {
09763                                         angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255 + M_PI;
09764                                         if (angle > M_PI * 2)
09765                                                 angle -= (float)M_PI * 2;
09766                                         dir[0] = sin(angle) * 20;
09767                                         dir[1] = cos(angle) * 20;
09768                                         dir[2] = cos(angle) * 20;
09769                                         VectorAdd(elevated, dir, holoRef.origin);
09770 
09771                                         angles[0] = cos(angle - 0.5 * M_PI) * 30;
09772                                         angles[1] = 360 - (angle * 180 / M_PI);
09773                                         if (angles[1] > 360)
09774                                                 angles[1] -= 360;
09775                                         angles[2] = 0;
09776                                         AnglesToAxis( angles, holoRef.axis );
09777                                 }
09778                                 else
09779                                 {
09780                                         angle = ((cg.time / 6) & 255) * (M_PI * 2) / 255 + 0.5 * M_PI;
09781                                         if (angle > M_PI * 2)
09782                                                 angle -= (float)M_PI * 2;
09783                                         dir[0] = sin(angle) * 20;
09784                                         dir[1] = cos(angle) * 20;
09785                                         dir[2] = 0;
09786                                         VectorAdd(elevated, dir, holoRef.origin);
09787                         
09788                                         VectorCopy(dir, holoRef.axis[1]);
09789                                         VectorNormalize(holoRef.axis[1]);
09790                                         VectorSet(holoRef.axis[2], 0, 0, 1);
09791                                         CrossProduct(holoRef.axis[1], holoRef.axis[2], holoRef.axis[0]);
09792                                 }
09793 
09794                                 holoRef.modelScale[0] = 0.5;
09795                                 holoRef.modelScale[1] = 0.5;
09796                                 holoRef.modelScale[2] = 0.5;
09797                                 ScaleModelAxis(&holoRef);
09798 
09799                                 {
09800                                         float wv;
09801                                         addspriteArgStruct_t fxSArgs;
09802                                         vec3_t holoCenter;
09803 
09804                                         holoCenter[0] = holoRef.origin[0] + holoRef.axis[2][0]*18;
09805                                         holoCenter[1] = holoRef.origin[1] + holoRef.axis[2][1]*18;
09806                                         holoCenter[2] = holoRef.origin[2] + holoRef.axis[2][2]*18;
09807 
09808                                         wv = sin( cg.time * 0.004f ) * 0.08f + 0.1f;
09809 
09810                                         VectorCopy(holoCenter, fxSArgs.origin);
09811                                         VectorClear(fxSArgs.vel);
09812                                         VectorClear(fxSArgs.accel);
09813                                         fxSArgs.scale = wv*60;
09814                                         fxSArgs.dscale = wv*60;
09815                                         fxSArgs.sAlpha = wv*12;
09816                                         fxSArgs.eAlpha = wv*12;
09817                                         fxSArgs.rotation = 0.0f;
09818                                         fxSArgs.bounce = 0.0f;
09819                                         fxSArgs.life = 1.0f;
09820 
09821                                         fxSArgs.flags = 0x08000000|0x00000001;
09822 
09823                                         if (forcePowerDarkLight[i] == FORCE_DARKSIDE)
09824                                         { //dark
09825                                                 fxSArgs.sAlpha *= 3;
09826                                                 fxSArgs.eAlpha *= 3;
09827                                                 fxSArgs.shader = cgs.media.redSaberGlowShader;
09828                                                 trap_FX_AddSprite(&fxSArgs);
09829                                         }
09830                                         else if (forcePowerDarkLight[i] == FORCE_LIGHTSIDE)
09831                                         { //light
09832                                                 fxSArgs.sAlpha *= 1.5;
09833                                                 fxSArgs.eAlpha *= 1.5;
09834                                                 fxSArgs.shader = cgs.media.redSaberGlowShader;
09835                                                 trap_FX_AddSprite(&fxSArgs);
09836                                                 fxSArgs.shader = cgs.media.greenSaberGlowShader;
09837                                                 trap_FX_AddSprite(&fxSArgs);
09838                                                 fxSArgs.shader = cgs.media.blueSaberGlowShader;
09839                                                 trap_FX_AddSprite(&fxSArgs);
09840                                         }
09841                                         else
09842                                         { //neutral
09843                                                 if (i == FP_SABER_OFFENSE ||
09844                                                         i == FP_SABER_DEFENSE ||
09845                                                         i == FP_SABERTHROW)
09846                                                 { //saber power
09847                                                         fxSArgs.sAlpha *= 1.5;
09848                                                         fxSArgs.eAlpha *= 1.5;
09849                                                         fxSArgs.shader = cgs.media.greenSaberGlowShader;
09850                                                         trap_FX_AddSprite(&fxSArgs);
09851                                                 }
09852                                                 else
09853                                                 {
09854                                                         fxSArgs.sAlpha *= 0.5;
09855                                                         fxSArgs.eAlpha *= 0.5;
09856                                                         fxSArgs.shader = cgs.media.greenSaberGlowShader;
09857                                                         trap_FX_AddSprite(&fxSArgs);
09858                                                         fxSArgs.shader = cgs.media.blueSaberGlowShader;
09859                                                         trap_FX_AddSprite(&fxSArgs);
09860                                                 }
09861                                         }
09862                                 }
09863 
09864                                 holoRef.hModel = trap_R_RegisterModel(forceHolocronModels[i]);
09865                                 trap_R_AddRefEntityToScene( &holoRef );
09866 
09867                                 renderedHolos++;
09868                         }
09869                         i++;
09870                 }
09871         }
09872 
09873         if ((cent->currentState.powerups & (1 << PW_YSALAMIRI)) ||
09874                 (cgs.gametype == GT_CTY && ((cent->currentState.powerups & (1 << PW_REDFLAG)) || (cent->currentState.powerups & (1 << PW_BLUEFLAG)))) )
09875         {
09876                 if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_REDFLAG)))
09877                 {
09878                         CG_DrawPlayerSphere(cent, cent->lerpOrigin, 1.4f, cgs.media.ysaliredShader );
09879                 }
09880                 else if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_BLUEFLAG)))
09881                 {
09882                         CG_DrawPlayerSphere(cent, cent->lerpOrigin, 1.4f, cgs.media.ysaliblueShader );
09883                 }
09884                 else
09885                 {
09886                         CG_DrawPlayerSphere(cent, cent->lerpOrigin, 1.4f, cgs.media.ysalimariShader );
09887                 }
09888         }
09889         
09890         if (cent->currentState.powerups & (1 << PW_FORCE_BOON))
09891         {
09892                 CG_DrawPlayerSphere(cent, cent->lerpOrigin, 2.0f, cgs.media.boonShader );
09893         }
09894 
09895         if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_DARK))
09896         {
09897                 CG_DrawPlayerSphere(cent, cent->lerpOrigin, 2.0f, cgs.media.endarkenmentShader );
09898         }
09899         else if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_LIGHT))
09900         {
09901                 CG_DrawPlayerSphere(cent, cent->lerpOrigin, 2.0f, cgs.media.enlightenmentShader );
09902         }
09903 
09904         if (cent->currentState.eFlags & EF_INVULNERABLE)
09905         {
09906                 CG_DrawPlayerSphere(cent, cent->lerpOrigin, 1.0f, cgs.media.invulnerabilityShader );
09907         }
09908 stillDoSaber:
09909         if ((cent->currentState.eFlags & EF_DEAD) && cent->currentState.weapon == WP_SABER)
09910         {
09911                 //cent->saberLength = 0;
09912                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
09913                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
09914 
09915                 drawPlayerSaber = qtrue;
09916         }
09917         else if (cent->currentState.weapon == WP_SABER 
09918                 && cent->currentState.saberHolstered < 2 )
09919         {
09920                 if ( (!cent->currentState.saberInFlight //saber not in flight
09921                                 || ci->saber[1].soundLoop) //???
09922                         && !(cent->currentState.eFlags & EF_DEAD))//still alive
09923                 {
09924                         vec3_t soundSpot;
09925                         qboolean didFirstSound = qfalse;
09926 
09927                         if (cg.snap->ps.clientNum == cent->currentState.number)
09928                         {
09929                                 //trap_S_AddLoopingSound( cent->currentState.number, cg.refdef.vieworg, vec3_origin, 
09930                                 //      trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" ) );
09931                                 VectorCopy(cg.refdef.vieworg, soundSpot);
09932                         }
09933                         else
09934                         {
09935                                 //trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, 
09936                                 //      trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" ) );
09937                                 VectorCopy(cent->lerpOrigin, soundSpot);
09938                         }
09939 
09940                         if (ci->saber[0].model[0] 
09941                                 && ci->saber[0].soundLoop 
09942                                 && !cent->currentState.saberInFlight)
09943                         {
09944                                 int i = 0;
09945                                 qboolean hasLen = qfalse;
09946 
09947                                 while (i < ci->saber[0].numBlades)
09948                                 {
09949                                         if (ci->saber[0].blade[i].length)
09950                                         {
09951                                                 hasLen = qtrue;
09952                                                 break;
09953                                         }
09954                                         i++;
09955                                 }
09956 
09957                                 if (hasLen)
09958                                 {
09959                                         trap_S_AddLoopingSound( cent->currentState.number, soundSpot, vec3_origin, 
09960                                                 ci->saber[0].soundLoop );
09961                                         didFirstSound = qtrue;
09962                                 }
09963                         }
09964                         if (ci->saber[1].model[0] 
09965                                 && ci->saber[1].soundLoop 
09966                                         && (!didFirstSound || ci->saber[0].soundLoop != ci->saber[1].soundLoop))
09967                         {
09968                                 int i = 0;
09969                                 qboolean hasLen = qfalse;
09970 
09971                                 while (i < ci->saber[1].numBlades)
09972                                 {
09973                                         if (ci->saber[1].blade[i].length)
09974                                         {
09975                                                 hasLen = qtrue;
09976                                                 break;
09977                                         }
09978                                         i++;
09979                                 }
09980 
09981                                 if (hasLen)
09982                                 {
09983                                         trap_S_AddLoopingSound( cent->currentState.number, soundSpot, vec3_origin, 
09984                                                 ci->saber[1].soundLoop );
09985                                 }
09986                         }
09987                 }
09988 
09989                 if (iwantout 
09990                         && !cent->currentState.saberInFlight)
09991                 {
09992                         if (cent->currentState.eFlags & EF_DEAD)
09993                         {
09994                                 if (cent->ghoul2 
09995                                         && cent->currentState.saberInFlight 
09996                                         && g2HasWeapon)
09997                                 { //special case, kill the saber on a freshly dead player if another source says to.
09998                                         trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
09999                                         g2HasWeapon = qfalse;
10000                                 }
10001                         }
10002                         return;
10003                         //goto endOfCall;
10004                 }
10005 
10006                 if (g2HasWeapon 
10007                         && cent->currentState.saberInFlight)
10008                 { //keep this set, so we don't re-unholster the thing when we get it back, even if it's knocked away.
10009                         cent->saberWasInFlight = qtrue;
10010                 }
10011 
10012                 if (cent->currentState.saberInFlight 
10013                         && cent->currentState.saberEntityNum)
10014                 {
10015                         centity_t *saberEnt;
10016 
10017                         saberEnt = &cg_entities[cent->currentState.saberEntityNum];
10018 
10019                         if ( g2HasWeapon || !cent->bolt3 ||
10020                                 saberEnt->serverSaberHitIndex != saberEnt->currentState.modelindex/*|| !cent->saberLength*/)
10021                         { //saber is in flight, do not have it as a standard weapon model
10022                                 qboolean addBolts = qfalse;
10023                                 mdxaBone_t boltMat;
10024 
10025                                 if (g2HasWeapon)
10026                                 {
10027                                         //ah well, just stick it over the right hand right now.
10028                                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_rhand, &boltMat, cent->turAngles, cent->lerpOrigin,
10029                                                 cg.time, cgs.gameModels, cent->modelScale);
10030                                         BG_GiveMeVectorFromMatrix(&boltMat, ORIGIN, saberEnt->currentState.pos.trBase);
10031 
10032                                         trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
10033                                         g2HasWeapon = qfalse;
10034                                 }
10035 
10036                                 //cent->bolt4 = 1;
10037 
10038                                 saberEnt->currentState.pos.trTime = cg.time;
10039                                 saberEnt->currentState.apos.trTime = cg.time;
10040 
10041                                 VectorCopy(saberEnt->currentState.pos.trBase, saberEnt->lerpOrigin);
10042                                 VectorCopy(saberEnt->currentState.apos.trBase, saberEnt->lerpAngles);
10043 
10044                                 cent->bolt3 = saberEnt->currentState.apos.trBase[0];
10045                                 if (!cent->bolt3)
10046                                 {
10047                                         cent->bolt3 = 1;
10048                                 }
10049                                 cent->bolt2 = 0;
10050 
10051                                 saberEnt->currentState.bolt2 = 123;
10052 
10053                                 if (saberEnt->ghoul2 &&
10054                                         saberEnt->serverSaberHitIndex == saberEnt->currentState.modelindex)
10055                                 {
10056                                         // now set up the gun bolt on it
10057                                         addBolts = qtrue;
10058                                 }
10059                                 else
10060                                 {
10061                                         const char *saberModel = CG_ConfigString( CS_MODELS+saberEnt->currentState.modelindex );
10062 
10063                                         saberEnt->serverSaberHitIndex = saberEnt->currentState.modelindex;
10064 
10065                                         if (saberEnt->ghoul2)
10066                                         { //clean if we already have one (because server changed model string index)
10067                                                 trap_G2API_CleanGhoul2Models(&(saberEnt->ghoul2));
10068                                                 saberEnt->ghoul2 = 0;
10069                                         }
10070 
10071                                         if (saberModel && saberModel[0])
10072                                         {
10073                                                 trap_G2API_InitGhoul2Model(&saberEnt->ghoul2, saberModel, 0, 0, 0, 0, 0);
10074                                         }
10075                                         else if (ci->saber[0].model[0])
10076                                         {
10077                                                 trap_G2API_InitGhoul2Model(&saberEnt->ghoul2, ci->saber[0].model, 0, 0, 0, 0, 0);
10078                                         }
10079                                         else
10080                                         {
10081                                                 trap_G2API_InitGhoul2Model(&saberEnt->ghoul2, "models/weapons2/saber/saber_w.glm", 0, 0, 0, 0, 0);
10082                                         }
10083                                         //trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, &saberEnt->ghoul2);
10084 
10085                                         if (saberEnt->ghoul2)
10086                                         {
10087                                                 addBolts = qtrue;
10088                                                 //cent->bolt4 = 2;
10089                                                 
10090                                                 VectorCopy(saberEnt->currentState.pos.trBase, saberEnt->lerpOrigin);
10091                                                 VectorCopy(saberEnt->currentState.apos.trBase, saberEnt->lerpAngles);
10092                                                 saberEnt->currentState.pos.trTime = cg.time;
10093                                                 saberEnt->currentState.apos.trTime = cg.time;
10094                                         }
10095                                 }
10096 
10097                                 if (addBolts)
10098                                 {
10099                                         int m = 0;
10100                                         int tagBolt;
10101                                         char *tagName;
10102 
10103                                         while (m < ci->saber[0].numBlades)
10104                                         {
10105                                                 tagName = va("*blade%i", m+1);
10106                                                 tagBolt = trap_G2API_AddBolt(saberEnt->ghoul2, 0, tagName);
10107 
10108                                                 if (tagBolt == -1)
10109                                                 {
10110                                                         if (m == 0)
10111                                                         { //guess this is an 0ldsk3wl saber
10112                                                                 tagBolt = trap_G2API_AddBolt(saberEnt->ghoul2, 0, "*flash");
10113 
10114                                                                 if (tagBolt == -1)
10115                                                                 {
10116                                                                         assert(0);
10117                                                                 }
10118                                                                 break;
10119                                                         }
10120 
10121                                                         if (tagBolt == -1)
10122                                                         {
10123                                                                 assert(0);
10124                                                                 break;
10125                                                         }
10126                                                 }
10127 
10128                                                 m++;
10129                                         }
10130                                 }
10131                         }
10132                         /*else if (cent->bolt4 != 2)
10133                         {
10134                                 if (saberEnt->ghoul2)
10135                                 {
10136                                         trap_G2API_AddBolt(saberEnt->ghoul2, 0, "*flash");
10137                                         cent->bolt4 = 2;
10138                                 }
10139                         }*/
10140 
10141                         if (saberEnt && saberEnt->ghoul2 /*&& cent->bolt4 == 2*/)
10142                         {
10143                                 vec3_t bladeAngles;
10144                                 vec3_t tAng;
10145                                 vec3_t efOrg;
10146                                 float wv;
10147                                 int k = 0;
10148                                 int l = 0;
10149                                 addspriteArgStruct_t fxSArgs;
10150 
10151                                 if (!cent->bolt2)
10152                                 {
10153                                         cent->bolt2 = cg.time;
10154                                 }
10155 
10156                                 if (cent->bolt3 != 90)
10157                                 {
10158                                         if (cent->bolt3 < 90)
10159                                         {
10160                                                 cent->bolt3 += (cg.time - cent->bolt2)*0.5;
10161 
10162                                                 if (cent->bolt3 > 90)
10163                                                 {
10164                                                         cent->bolt3 = 90;
10165                                                 }
10166                                         }
10167                                         else if (cent->bolt3 > 90)
10168                                         {
10169                                                 cent->bolt3 -= (cg.time - cent->bolt2)*0.5;
10170 
10171                                                 if (cent->bolt3 < 90)
10172                                                 {
10173                                                         cent->bolt3 = 90;
10174                                                 }
10175                                         }
10176                                 }
10177 
10178                                 cent->bolt2 = cg.time;
10179 
10180                                 saberEnt->currentState.apos.trBase[0] = cent->bolt3;
10181                                 saberEnt->lerpAngles[0] = cent->bolt3;
10182 
10183                                 if (!saberEnt->currentState.saberInFlight && saberEnt->currentState.bolt2 != 123)
10184                                 { //owner is pulling is back
10185                                         if ( !(ci->saber[0].saberFlags&SFL_RETURN_DAMAGE)
10186                                                 || cent->currentState.saberHolstered )
10187                                         {
10188                                                 vec3_t owndir;
10189 
10190                                                 VectorSubtract(saberEnt->lerpOrigin, cent->lerpOrigin, owndir);
10191                                                 VectorNormalize(owndir);
10192 
10193                                                 vectoangles(owndir, owndir);
10194 
10195                                                 owndir[0] += 90;
10196 
10197                                                 VectorCopy(owndir, saberEnt->currentState.apos.trBase);
10198                                                 VectorCopy(owndir, saberEnt->lerpAngles);
10199                                                 VectorClear(saberEnt->currentState.apos.trDelta);
10200                                         }
10201                                 }
10202 
10203                                 //We don't actually want to rely entirely on server updates to render the position of the saber, because we actually know generally where
10204                                 //it's going to be before the first position update even gets here, and it needs to start getting rendered the instant the saber model is
10205                                 //removed from the player hand. So we'll just render it manually and let normal rendering for the entity be ignored.
10206                                 if (!saberEnt->currentState.saberInFlight && saberEnt->currentState.bolt2 != 123)
10207                                 { //tell it that we're a saber and to render the glow around our handle because we're being pulled back
10208                                         saberEnt->bolt3 = 999;
10209                                 }
10210 
10211                                 saberEnt->currentState.modelGhoul2 = 1;
10212                                 CG_ManualEntityRender(saberEnt);
10213                                 saberEnt->bolt3 = 0;
10214                                 saberEnt->currentState.modelGhoul2 = 127;
10215 
10216                                 VectorCopy(saberEnt->lerpAngles, bladeAngles);
10217                                 bladeAngles[ROLL] = 0;
10218 
10219                                 if ( ci->saber[0].numBlades > 1//staff
10220                                         && cent->currentState.saberHolstered == 1 )//extra blades off
10221                                 {//only first blade should be on
10222                                         BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10223                                         BG_SI_SetDesiredLength(&ci->saber[0], -1, 0);
10224                                 }
10225                                 else
10226                                 {
10227                                         BG_SI_SetDesiredLength(&ci->saber[0], -1, -1);
10228                                 }
10229                                 if ( ci->saber[1].model //dual sabers
10230                                         && cent->currentState.saberHolstered == 1 )//second one off
10231                                 {
10232                                         BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10233                                 }
10234                                 else
10235                                 {
10236                                         BG_SI_SetDesiredLength(&ci->saber[1], -1, -1);
10237                                 }
10238 
10239                                 //while (l < MAX_SABERS)
10240                                 //Only want to do for the first saber actually, it's the one in flight.
10241                                 while (l < 1)
10242                                 {
10243                                         if (!ci->saber[l].model[0])
10244                                         {
10245                                                 break;
10246                                         }
10247 
10248                                         k = 0;
10249                                         while (k < ci->saber[l].numBlades)
10250                                         {
10251                                                 if ( //cent->currentState.fireflag == SS_STAFF&& //in saberstaff style
10252                                                         l == 0//first saber
10253                                                         && cent->currentState.saberHolstered == 1 //extra blades should be off
10254                                                         && k > 0 )//this is an extra blade
10255                                                 {//extra blades off
10256                                                         //don't draw them
10257                                                         CG_AddSaberBlade(cent, saberEnt, NULL, 0, 0, l, k, saberEnt->lerpOrigin, bladeAngles, qtrue, qtrue);
10258                                                 }
10259                                                 else
10260                                                 {
10261                                                         CG_AddSaberBlade(cent, saberEnt, NULL, 0, 0, l, k, saberEnt->lerpOrigin, bladeAngles, qtrue, qfalse);
10262                                                 }
10263 
10264                                                 k++;
10265                                         }
10266                                         if ( ci->saber[l].numBlades > 2 )
10267                                         {//add a single glow for the saber based on all the blade colors combined
10268                                                 CG_DoSaberLight( &ci->saber[l] );
10269                                         }
10270 
10271                                         l++;
10272                                 }
10273 
10274                                 //Make the player's hand glow while guiding the saber
10275                                 VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
10276 
10277                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, ci->bolt_rhand, &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
10278 
10279                                 efOrg[0] = boltMatrix.matrix[0][3];
10280                                 efOrg[1] = boltMatrix.matrix[1][3];
10281                                 efOrg[2] = boltMatrix.matrix[2][3];
10282 
10283                                 wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f;
10284 
10285                                 //trap_FX_AddSprite( NULL, efOrg, NULL, NULL, 8.0f, 8.0f, wv, wv, 0.0f, 0.0f, 1.0f, cgs.media.yellowSaberGlowShader, 0x08000000 );
10286                                 VectorCopy(efOrg, fxSArgs.origin);
10287                                 VectorClear(fxSArgs.vel);
10288                                 VectorClear(fxSArgs.accel);
10289                                 fxSArgs.scale = 8.0f;
10290                                 fxSArgs.dscale = 8.0f;
10291                                 fxSArgs.sAlpha = wv;
10292                                 fxSArgs.eAlpha = wv;
10293                                 fxSArgs.rotation = 0.0f;
10294                                 fxSArgs.bounce = 0.0f;
10295                                 fxSArgs.life = 1.0f;
10296                                 fxSArgs.shader = cgs.media.yellowDroppedSaberShader;
10297                                 fxSArgs.flags = 0x08000000;
10298                                 trap_FX_AddSprite(&fxSArgs);
10299                         }
10300                 }
10301                 else
10302                 {
10303                         if ( ci->saber[0].numBlades > 1//staff
10304                                 && cent->currentState.saberHolstered == 1 )//extra blades off
10305                         {//only first blade should be on
10306                                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10307                                 BG_SI_SetDesiredLength(&ci->saber[0], -1, 0);
10308                         }
10309                         else
10310                         {
10311                                 BG_SI_SetDesiredLength(&ci->saber[0], -1, -1);
10312                         }
10313                         if ( ci->saber[1].model //dual sabers
10314                                 && cent->currentState.saberHolstered == 1 )//second one off
10315                         {
10316                                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10317                         }
10318                         else
10319                         {
10320                                 BG_SI_SetDesiredLength(&ci->saber[1], -1, -1);
10321                         }
10322                 }
10323 
10324                 //If the arm the saber is in is broken, turn it off.
10325                 /*
10326                 if (cent->currentState.brokenLimbs & (1 << BROKENLIMB_RARM))
10327                 {
10328                         BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10329                 }
10330                 */
10331                 //Leaving right arm on, at least for now.
10332                 if (cent->currentState.brokenLimbs & (1 << BROKENLIMB_LARM))
10333                 {
10334                         BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10335                 }
10336 
10337                 if (!cent->currentState.saberEntityNum)
10338                 {
10339                         BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10340                         //BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10341                 }
10342                 /*
10343                 else
10344                 {
10345                         BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10346                         BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10347                 }
10348                 */
10349                 drawPlayerSaber = qtrue;
10350         }
10351         else if (cent->currentState.weapon == WP_SABER)
10352         {
10353                 //cent->saberLength = 0;
10354                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10355                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10356 
10357                 drawPlayerSaber = qtrue;
10358         }
10359         else
10360         {
10361                 //cent->saberLength = 0;
10362                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10363                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10364 
10365                 BG_SI_SetLength(&ci->saber[0], 0);
10366                 BG_SI_SetLength(&ci->saber[1], 0);
10367         }
10368 
10369 #ifdef _RAG_BOLT_TESTING
10370         if (cent->currentState.eFlags & EF_RAG)
10371         {
10372                 CG_TempTestFunction(cent, cent->turAngles);
10373         }
10374 #endif
10375 
10376         if (cent->currentState.weapon == WP_SABER)
10377         {
10378                 BG_SI_SetLengthGradual(&ci->saber[0], cg.time);
10379                 BG_SI_SetLengthGradual(&ci->saber[1], cg.time);
10380         }
10381 
10382         if (drawPlayerSaber)
10383         {
10384                 centity_t *saberEnt;
10385                 int k = 0;
10386                 int l = 0;
10387 
10388                 if (!cent->currentState.saberEntityNum)
10389                 {
10390                         l = 1; //The "primary" saber is missing or in flight or something, so only try to draw in the second one
10391                 }
10392                 else if (!cent->currentState.saberInFlight)
10393                 {
10394                         saberEnt = &cg_entities[cent->currentState.saberEntityNum];
10395 
10396                         if (/*cent->bolt4 && */!g2HasWeapon)
10397                         {
10398                                 trap_G2API_CopySpecificGhoul2Model(CG_G2WeaponInstance(cent, WP_SABER), 0, cent->ghoul2, 1);
10399 
10400                                 if (saberEnt && saberEnt->ghoul2)
10401                                 {
10402                                         trap_G2API_CleanGhoul2Models(&(saberEnt->ghoul2));
10403                                 }
10404 
10405                                 saberEnt->currentState.modelindex = 0;
10406                                 saberEnt->ghoul2 = NULL;
10407                                 VectorClear(saberEnt->currentState.pos.trBase);
10408                         }
10409 
10410                         cent->bolt3 = 0;
10411                         cent->bolt2 = 0;
10412                 }
10413                 else
10414                 {
10415                         l = 1; //The "primary" saber is missing or in flight or something, so only try to draw in the second one
10416                 }
10417 
10418                 while (l < MAX_SABERS)
10419                 {
10420                         k = 0;
10421 
10422                         if (!ci->saber[l].model[0])
10423                         {
10424                                 break;
10425                         }
10426 
10427                         if (cent->currentState.eFlags2&EF2_HELD_BY_MONSTER)
10428                         {
10429                                 //vectoangles(legs.axis[0], rootAngles);
10430 #if 0
10431                                 if ( cent->currentState.hasLookTarget )//NOTE: lookTarget is an entity number, so this presumes that client 0 is NOT a Rancor...
10432                                 {
10433                                         centity_t       *rancor = &cg_entities[cent->currentState.lookTarget];
10434                                         if ( rancor && rancor->ghoul2 )
10435                                         {
10436                                                 BG_AttachToRancor( rancor->ghoul2, //ghoul2 info
10437                                                         rancor->lerpAngles[YAW],
10438                                                         rancor->lerpOrigin,
10439                                                         cg.time,
10440                                                         cgs.gameModels,
10441                                                         rancor->modelScale,
10442                                                         (rancor->currentState.eFlags2&EF2_GENERIC_NPC_FLAG),
10443                                                         legs.origin,
10444                                                         rootAngles,
10445                                                         NULL );
10446                                         }
10447                                 }
10448 #else
10449                                 vectoangles(legs.axis[0], rootAngles);
10450 #endif
10451                         }
10452 
10453                         while (k < ci->saber[l].numBlades)
10454                         {
10455                                 if ( //cent->currentState.fireflag == SS_STAFF&& //in saberstaff style
10456                                         cent->currentState.saberHolstered == 1 //extra blades should be off
10457                                         && k > 0 //this is an extra blade
10458                                         && ci->saber[l].blade[k].length <= 0 )//it's completely off
10459                                 {//extra blades off
10460                                         //don't draw them
10461                                         CG_AddSaberBlade( cent, cent, NULL, 0, 0, l, k, legs.origin, rootAngles, qfalse, qtrue);
10462                                 }
10463                                 else if ( ci->saber[1].model[0]//we have a second saber
10464                                         && cent->currentState.saberHolstered == 1 //it should be off
10465                                         && l > 0//and this is the second one
10466                                         && ci->saber[l].blade[k].length <= 0 )//it's completely off
10467                                 {//second saber is turned off and this blade is done with turning off
10468                                         CG_AddSaberBlade( cent, cent, NULL, 0, 0, l, k, legs.origin, rootAngles, qfalse, qtrue);
10469                                 }
10470                                 else
10471                                 {
10472                                         CG_AddSaberBlade( cent, cent, NULL, 0, 0, l, k, legs.origin, rootAngles, qfalse, qfalse);
10473                                 }
10474 
10475                                 k++;
10476                         }
10477                         if ( ci->saber[l].numBlades > 2 )
10478                         {//add a single glow for the saber based on all the blade colors combined
10479                                 CG_DoSaberLight( &ci->saber[l] );
10480                         }
10481 
10482                         l++;
10483                 }
10484         }
10485 
10486         if (cent->currentState.saberInFlight && !cent->currentState.saberEntityNum)
10487         { //reset the length if the saber is knocked away
10488                 BG_SI_SetDesiredLength(&ci->saber[0], 0, -1);
10489                 BG_SI_SetDesiredLength(&ci->saber[1], 0, -1);
10490 
10491                 if (g2HasWeapon)
10492                 { //and remember to kill the bolton model in case we didn't get a thrown saber update first
10493                         trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
10494                         g2HasWeapon = qfalse;
10495                 }
10496                 cent->bolt3 = 0;
10497                 cent->bolt2 = 0;
10498         }
10499 
10500         if (cent->currentState.eFlags & EF_DEAD)
10501         {
10502                 if (cent->ghoul2 && cent->currentState.saberInFlight && g2HasWeapon)
10503                 { //special case, kill the saber on a freshly dead player if another source says to.
10504                         trap_G2API_RemoveGhoul2Model(&(cent->ghoul2), 1);
10505                         g2HasWeapon = qfalse;
10506                 }
10507         }
10508 
10509         if (iwantout)
10510         {
10511                 return;
10512                 //goto endOfCall;
10513         }
10514 
10515         if ((cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) && cg.snap->ps.clientNum != cent->currentState.number)
10516         {
10517                 legs.shaderRGBA[0] = 255;
10518                 legs.shaderRGBA[1] = 255;
10519                 legs.shaderRGBA[2] = 0;
10520                 legs.renderfx |= RF_MINLIGHT;
10521         }
10522 
10523         if (cg.snap->ps.duelInProgress /*&& cent->currentState.number != cg.snap->ps.clientNum*/)
10524         { //I guess go ahead and glow your own client too in a duel
10525                 if (cent->currentState.number != cg.snap->ps.duelIndex &&
10526                         cent->currentState.number != cg.snap->ps.clientNum)
10527                 { //everyone not involved in the duel is drawn very dark
10528                         legs.shaderRGBA[0] /= 5.0f;
10529                         legs.shaderRGBA[1] /= 5.0f;
10530                         legs.shaderRGBA[2] /= 5.0f;
10531                         legs.renderfx |= RF_RGB_TINT;
10532                 }
10533                 else
10534                 { //adjust the glow by how far away you are from your dueling partner
10535                         centity_t *duelEnt;
10536 
10537                         duelEnt = &cg_entities[cg.snap->ps.duelIndex];
10538                         
10539                         if (duelEnt)
10540                         {
10541                                 vec3_t vecSub;
10542                                 float subLen = 0;
10543 
10544                                 VectorSubtract(duelEnt->lerpOrigin, cg.snap->ps.origin, vecSub);
10545                                 subLen = VectorLength(vecSub);
10546 
10547                                 if (subLen < 1)
10548                                 {
10549                                         subLen = 1;
10550                                 }
10551 
10552                                 if (subLen > 1020)
10553                                 {
10554                                         subLen = 1020;
10555                                 }
10556 
10557                                 {
10558                                 const unsigned char savRGBA[3] = {legs.shaderRGBA[0],legs.shaderRGBA[1],legs.shaderRGBA[2]};
10559                                 legs.shaderRGBA[0] = max(255-subLen/4,1);
10560                                 legs.shaderRGBA[1] = max(255-subLen/4,1);
10561                                 legs.shaderRGBA[2] = max(255-subLen/4,1);
10562 
10563                                 legs.renderfx &= ~RF_RGB_TINT;
10564                                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10565                                 legs.customShader = cgs.media.forceShell;
10566                 
10567                                 trap_R_AddRefEntityToScene( &legs );    //draw the shell
10568 
10569                                 legs.customShader = 0;  //reset to player model
10570 
10571                                 legs.shaderRGBA[0] = max(savRGBA[0]-subLen/8,1);
10572                                 legs.shaderRGBA[1] = max(savRGBA[1]-subLen/8,1);
10573                                 legs.shaderRGBA[2] = max(savRGBA[2]-subLen/8,1);
10574                                 }
10575 
10576                                 if (subLen <= 1024)
10577                                 {
10578                                         legs.renderfx |= RF_RGB_TINT;
10579                                 }
10580                         }
10581                 }
10582         }
10583         else
10584         {
10585                 if (cent->currentState.bolt1 && !(cent->currentState.eFlags & EF_DEAD) && cent->currentState.number != cg.snap->ps.clientNum && (!cg.snap->ps.duelInProgress || cg.snap->ps.duelIndex != cent->currentState.number))
10586                 {
10587                         legs.shaderRGBA[0] = 50;
10588                         legs.shaderRGBA[1] = 50;
10589                         legs.shaderRGBA[2] = 50;
10590                         legs.renderfx |= RF_RGB_TINT;
10591                 }
10592         }
10593 
10594         if (cent->currentState.eFlags & EF_DISINTEGRATION)
10595         {
10596                 if (!cent->dustTrailTime)
10597                 {
10598                         cent->dustTrailTime = cg.time;
10599                         cent->miscTime = legs.frame;
10600                 }
10601 
10602                 if ((cg.time - cent->dustTrailTime) > 1500)
10603                 { //avoid rendering the entity after disintegration has finished anyway
10604                         //goto endOfCall;
10605                         return;
10606                 }
10607 
10608                 trap_G2API_SetBoneAnim(legs.ghoul2, 0, "model_root", cent->miscTime, cent->miscTime, BONE_ANIM_OVERRIDE_FREEZE, 1.0f, cg.time, cent->miscTime, -1);
10609 
10610                 if (!cent->noLumbar)
10611                 {
10612                         trap_G2API_SetBoneAnim(legs.ghoul2, 0, "lower_lumbar", cent->miscTime, cent->miscTime, BONE_ANIM_OVERRIDE_FREEZE, 1.0f, cg.time, cent->miscTime, -1);
10613 
10614                         if (cent->localAnimIndex <= 1)
10615                         {
10616                                 trap_G2API_SetBoneAnim(legs.ghoul2, 0, "Motion", cent->miscTime, cent->miscTime, BONE_ANIM_OVERRIDE_FREEZE, 1.0f, cg.time, cent->miscTime, -1);
10617                         }
10618                 }
10619 
10620                 CG_Disintegration(cent, &legs);
10621 
10622                 //goto endOfCall;
10623                 return;
10624         }
10625         else
10626         {
10627                 cent->dustTrailTime = 0;
10628                 cent->miscTime = 0;
10629         }
10630 
10631         if (cent->currentState.powerups & (1 << PW_CLOAKED))
10632         {
10633                 if (!cent->cloaked)
10634                 {
10635                         cent->cloaked = qtrue;
10636                         cent->uncloaking = cg.time + 2000;
10637                 }
10638         }
10639         else if (cent->cloaked)
10640         {
10641                 cent->cloaked = qfalse;
10642                 cent->uncloaking = cg.time + 2000;
10643         }
10644 
10645         if (cent->uncloaking > cg.time)
10646         {//in the middle of cloaking
10647                 if ((cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) 
10648                         && cg.snap->ps.clientNum != cent->currentState.number)
10649                 {//just draw him
10650                         trap_R_AddRefEntityToScene( &legs );
10651                 }
10652                 else
10653                 {
10654                         float perc = (float)(cent->uncloaking - cg.time) / 2000.0f;
10655                         if (( cent->currentState.powerups & ( 1 << PW_CLOAKED ))) 
10656                         {//actually cloaking, so reverse it
10657                                 perc = 1.0f - perc;
10658                         }
10659 
10660                         if ( perc >= 0.0f && perc <= 1.0f )
10661                         {
10662                                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10663                                 legs.renderfx |= RF_RGB_TINT;
10664                                 legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = 255.0f * perc;
10665                                 legs.shaderRGBA[3] = 0;
10666                                 legs.customShader = cgs.media.cloakedShader;
10667                                 trap_R_AddRefEntityToScene( &legs );
10668 
10669                                 legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = 255;
10670                                 legs.shaderRGBA[3] = 255 * (1.0f - perc); // let model alpha in
10671                                 legs.customShader = 0; // use regular skin
10672                                 legs.renderfx &= ~RF_RGB_TINT;
10673                                 legs.renderfx |= RF_FORCE_ENT_ALPHA;
10674                                 trap_R_AddRefEntityToScene( &legs );
10675                         }
10676                 }
10677         }
10678         else if (( cent->currentState.powerups & ( 1 << PW_CLOAKED ))) 
10679         {//fully cloaked
10680                 if ((cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) 
10681                         && cg.snap->ps.clientNum != cent->currentState.number)
10682                 {//just draw him
10683                         trap_R_AddRefEntityToScene( &legs );
10684                 }
10685                 else
10686                 {
10687                         if (cg.renderingThirdPerson || cent->currentState.number != cg.predictedPlayerState.clientNum)
10688                         {
10689                                 /*
10690                                 legs.renderfx = 0;//&= ~(RF_RGB_TINT|RF_ALPHA_FADE);
10691                                 legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = legs.shaderRGBA[3] = 255;
10692                                 legs.customShader = cgs.media.cloakedShader;
10693 
10694                                 legs.nonNormalizedAxes = qtrue;
10695 
10696                                 legs.modelScale[0] = 1.02f;
10697                                 legs.modelScale[1] = 1.02f;
10698                                 legs.modelScale[2] = 1.02f;
10699                                 VectorScale( legs.axis[0], legs.modelScale[0], legs.axis[0] );
10700                                 VectorScale( legs.axis[1], legs.modelScale[1], legs.axis[1] );
10701                                 VectorScale( legs.axis[2], legs.modelScale[2], legs.axis[2] );
10702 
10703                                 ScaleModelAxis(&legs);
10704 
10705                                 trap_R_AddRefEntityToScene( &legs );
10706                                 
10707                                 legs.modelScale[0] = 0.98f;
10708                                 legs.modelScale[1] = 0.98f;
10709                                 legs.modelScale[2] = 0.98f;
10710                                 VectorScale( legs.axis[0], legs.modelScale[0], legs.axis[0] );
10711                                 VectorScale( legs.axis[1], legs.modelScale[1], legs.axis[1] );
10712                                 VectorScale( legs.axis[2], legs.modelScale[2], legs.axis[2] );
10713 
10714                                 ScaleModelAxis(&legs);
10715                                 */
10716 
10717                                 if (cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4 && cg_renderToTextureFX.integer)
10718                                 {
10719                                         trap_R_SetRefractProp(1.0f, 0.0f, qfalse, qfalse); //don't need to do this every frame.. but..
10720                                         legs.customShader = 2; //crazy "refractive" shader
10721                                         trap_R_AddRefEntityToScene( &legs );
10722                                         legs.customShader = 0;
10723                                 }
10724                                 else
10725                                 { //stencil buffer's in use, sorry
10726                                         legs.renderfx = 0;//&= ~(RF_RGB_TINT|RF_ALPHA_FADE);
10727                                         legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = legs.shaderRGBA[3] = 255;
10728                                         legs.customShader = cgs.media.cloakedShader;
10729                                         trap_R_AddRefEntityToScene( &legs );
10730                                         legs.customShader = 0;
10731                                 }
10732                         }
10733                 }
10734         }
10735 
10736         if (!(cent->currentState.powerups & (1 << PW_CLOAKED)))
10737         { //don't add the normal model if cloaked
10738                 CG_CheckThirdPersonAlpha( cent, &legs );
10739                 trap_R_AddRefEntityToScene(&legs);
10740         }
10741 
10742         //cent->frame_minus2 = cent->frame_minus1;
10743         VectorCopy(cent->frame_minus1, cent->frame_minus2);
10744         
10745         if (cent->frame_minus1_refreshed)
10746         {
10747                 cent->frame_minus2_refreshed = 1;
10748         }
10749 
10750         //cent->frame_minus1 = legs;
10751         VectorCopy(legs.origin, cent->frame_minus1);
10752 
10753         cent->frame_minus1_refreshed = 1;
10754 
10755         if (!cent->frame_hold_refreshed && (cent->currentState.powerups & (1 << PW_SPEEDBURST)))
10756         {
10757                 cent->frame_hold_time = cg.time + 254;
10758         }
10759 
10760         if (cent->frame_hold_time >= cg.time)
10761         {
10762                 refEntity_t reframe_hold;
10763 
10764                 if (!cent->frame_hold_refreshed)
10765                 { //We're taking the ghoul2 instance from the original refent and duplicating it onto our refent alias so that we can then freeze the frame and fade it for the effect
10766                         if (cent->frame_hold && trap_G2_HaveWeGhoul2Models(cent->frame_hold) &&
10767                                 cent->frame_hold != cent->ghoul2)
10768                         {
10769                                 trap_G2API_CleanGhoul2Models(&(cent->frame_hold));
10770                         }
10771                         reframe_hold = legs;
10772                         cent->frame_hold_refreshed = 1;
10773                         reframe_hold.ghoul2 = NULL;
10774         
10775                         trap_G2API_DuplicateGhoul2Instance(cent->ghoul2, &cent->frame_hold);
10776 
10777                         //Set the animation to the current frame and freeze on end
10778                         //trap_G2API_SetBoneAnim(cent->frame_hold.ghoul2, 0, "model_root", cent->frame_hold.frame, cent->frame_hold.frame, BONE_ANIM_OVERRIDE_FREEZE, 1.0f, cg.time, cent->frame_hold.frame, -1);
10779                         trap_G2API_SetBoneAnim(cent->frame_hold, 0, "model_root", legs.frame, legs.frame, 0, 1.0f, cg.time, legs.frame, -1);
10780                 }
10781                 else
10782                 {
10783                         reframe_hold = legs;
10784                         reframe_hold.ghoul2 = cent->frame_hold;
10785                 }
10786 
10787                 reframe_hold.renderfx |= RF_FORCE_ENT_ALPHA;
10788                 reframe_hold.shaderRGBA[3] = (cent->frame_hold_time - cg.time);
10789                 if (reframe_hold.shaderRGBA[3] > 254)
10790                 {
10791                         reframe_hold.shaderRGBA[3] = 254;
10792                 }
10793                 if (reframe_hold.shaderRGBA[3] < 1)
10794                 {
10795                         reframe_hold.shaderRGBA[3] = 1;
10796                 }
10797 
10798                 reframe_hold.ghoul2 = cent->frame_hold;
10799                 trap_R_AddRefEntityToScene(&reframe_hold);
10800         }
10801         else
10802         {
10803                 cent->frame_hold_refreshed = 0;
10804         }
10805 
10806         //
10807         // add the gun / barrel / flash
10808         //
10809         if (cent->currentState.weapon != WP_EMPLACED_GUN)
10810         {
10811                 CG_AddPlayerWeapon( &legs, NULL, cent, ci->team, rootAngles, qtrue );
10812         }
10813         // add powerups floating behind the player
10814         CG_PlayerPowerups( cent, &legs );
10815 
10816         if ((cent->currentState.forcePowersActive & (1 << FP_RAGE)) &&
10817                 (cg.renderingThirdPerson || cent->currentState.number != cg.snap->ps.clientNum))
10818         {
10819                 //legs.customShader = cgs.media.rageShader;
10820                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10821                 legs.renderfx &= ~RF_MINLIGHT;
10822 
10823                 legs.renderfx |= RF_RGB_TINT;
10824                 legs.shaderRGBA[0] = 255;
10825                 legs.shaderRGBA[1] = legs.shaderRGBA[2] = 0;
10826                 legs.shaderRGBA[3] = 255;
10827 
10828                 if ( rand() & 1 )
10829                 {
10830                         legs.customShader = cgs.media.electricBodyShader;       
10831                 }
10832                 else
10833                 {
10834                         legs.customShader = cgs.media.electricBody2Shader;
10835                 }
10836 
10837                 trap_R_AddRefEntityToScene(&legs);
10838         }
10839 
10840         if (!cg.snap->ps.duelInProgress && cent->currentState.bolt1 && !(cent->currentState.eFlags & EF_DEAD) && cent->currentState.number != cg.snap->ps.clientNum && (!cg.snap->ps.duelInProgress || cg.snap->ps.duelIndex != cent->currentState.number))
10841         {
10842                 legs.shaderRGBA[0] = 50;
10843                 legs.shaderRGBA[1] = 50;
10844                 legs.shaderRGBA[2] = 255;
10845 
10846                 legs.renderfx &= ~RF_RGB_TINT;
10847                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10848                 legs.customShader = cgs.media.forceSightBubble;
10849                 
10850                 trap_R_AddRefEntityToScene( &legs );
10851         }
10852 
10853         if ( CG_VehicleShouldDrawShields( cent ) //vehicle
10854                 || (checkDroidShields && CG_VehicleShouldDrawShields( &cg_entities[cent->currentState.m_iVehicleNum] )) )//droid in vehicle
10855         {//Vehicles have form-fitting shields
10856                 Vehicle_t *pVeh = cent->m_pVehicle;
10857                 if ( checkDroidShields )
10858                 {
10859                         pVeh = cg_entities[cent->currentState.m_iVehicleNum].m_pVehicle;
10860                 }
10861                 legs.shaderRGBA[0] = 255;
10862                 legs.shaderRGBA[1] = 255;
10863                 legs.shaderRGBA[2] = 255;
10864                 legs.shaderRGBA[3] = 10.0f+(sin((float)(cg.time/4))*128.0f);//112.0 * ((cent->damageTime - cg.time) / MIN_SHIELD_TIME) + random()*16;
10865 
10866                 legs.renderfx &= ~RF_RGB_TINT;
10867                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10868 
10869                 if ( pVeh 
10870                         && pVeh->m_pVehicleInfo
10871                         && pVeh->m_pVehicleInfo->shieldShaderHandle )
10872                 {//use the vehicle-specific shader
10873                         legs.customShader = pVeh->m_pVehicleInfo->shieldShaderHandle;
10874                 }
10875                 else
10876                 {
10877                         legs.customShader = cgs.media.playerShieldDamage;
10878                 }
10879                 
10880                 trap_R_AddRefEntityToScene( &legs );
10881         }
10882         //For now, these two are using the old shield shader. This is just so that you
10883         //can tell it apart from the JM/duel shaders, but it's still very obvious.
10884         if (cent->currentState.forcePowersActive & (1 << FP_PROTECT))
10885         { //aborb is represented by green..
10886                 refEntity_t prot;
10887                 
10888                 memcpy(&prot, &legs, sizeof(prot));
10889 
10890                 prot.shaderRGBA[0] = 0;
10891                 prot.shaderRGBA[1] = 128;
10892                 prot.shaderRGBA[2] = 0;
10893                 prot.shaderRGBA[3] = 254;
10894 
10895                 prot.renderfx &= ~RF_RGB_TINT;
10896                 prot.renderfx &= ~RF_FORCE_ENT_ALPHA;
10897                 prot.customShader = cgs.media.protectShader;
10898 
10899                 /*
10900                 if (!prot.modelScale[0] && !prot.modelScale[1] && !prot.modelScale[2])
10901                 {
10902                         prot.modelScale[0] = prot.modelScale[1] = prot.modelScale[2] = 1.0f;
10903                 }
10904                 VectorScale(prot.modelScale, 1.1f, prot.modelScale);
10905                 prot.origin[2] -= 2.0f;
10906                 ScaleModelAxis(&prot);
10907                 */
10908 
10909                 trap_R_AddRefEntityToScene( &prot );
10910         }
10911         //if (cent->currentState.forcePowersActive & (1 << FP_ABSORB))
10912         //Showing only when the power has been active (absorbed something) recently now, instead of always.
10913         //AND
10914         //always show if it is you with the absorb on
10915         if ((cent->currentState.number == cg.predictedPlayerState.clientNum && (cg.predictedPlayerState.fd.forcePowersActive & (1<<FP_ABSORB))) ||
10916                 (cent->teamPowerEffectTime > cg.time && cent->teamPowerType == 3))
10917         { //aborb is represented by blue..
10918                 legs.shaderRGBA[0] = 0;
10919                 legs.shaderRGBA[1] = 0;
10920                 legs.shaderRGBA[2] = 255;
10921                 legs.shaderRGBA[3] = 254;
10922 
10923                 legs.renderfx &= ~RF_RGB_TINT;
10924                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10925                 legs.customShader = cgs.media.playerShieldDamage;
10926                 
10927                 trap_R_AddRefEntityToScene( &legs );
10928         }
10929 
10930         if (cent->currentState.isJediMaster && cg.snap->ps.clientNum != cent->currentState.number)
10931         {
10932                 legs.shaderRGBA[0] = 100;
10933                 legs.shaderRGBA[1] = 100;
10934                 legs.shaderRGBA[2] = 255;
10935 
10936                 legs.renderfx &= ~RF_RGB_TINT;
10937                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
10938                 legs.renderfx |= RF_NODEPTH;
10939                 legs.customShader = cgs.media.forceShell;
10940                 
10941                 trap_R_AddRefEntityToScene( &legs );
10942 
10943                 legs.renderfx &= ~RF_NODEPTH;
10944         }
10945 
10946         if ((cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE)) && cg.snap->ps.clientNum != cent->currentState.number && cg_auraShell.integer)
10947         {
10948                 if (cgs.gametype == GT_SIEGE)
10949                 {       // A team game
10950                         if ( ci->team == TEAM_SPECTATOR || ci->team == TEAM_FREE )
10951                         {//yellow
10952                                 legs.shaderRGBA[0] = 255;
10953                                 legs.shaderRGBA[1] = 255;
10954                                 legs.shaderRGBA[2] = 0;
10955                         }
10956                         else if ( ci->team != cgs.clientinfo[cg.snap->ps.clientNum].team )
10957                         {//red
10958                                 legs.shaderRGBA[0] = 255;
10959                                 legs.shaderRGBA[1] = 50;
10960                                 legs.shaderRGBA[2] = 50;
10961                         }
10962                         else
10963                         {//green
10964                                 legs.shaderRGBA[0] = 50;
10965                                 legs.shaderRGBA[1] = 255;
10966                                 legs.shaderRGBA[2] = 50;
10967                         }
10968                 }
10969                 else if (cgs.gametype >= GT_TEAM)
10970                 {       // A team game
10971                         switch(ci->team)
10972                         {
10973                         case TEAM_RED:
10974                                 legs.shaderRGBA[0] = 255;
10975                                 legs.shaderRGBA[1] = 50;
10976                                 legs.shaderRGBA[2] = 50;
10977                                 break;
10978                         case TEAM_BLUE:
10979                                 legs.shaderRGBA[0] = 75;
10980                                 legs.shaderRGBA[1] = 75;
10981                                 legs.shaderRGBA[2] = 255;
10982                                 break;
10983 
10984                         default:
10985                                 legs.shaderRGBA[0] = 255;
10986                                 legs.shaderRGBA[1] = 255;
10987                                 legs.shaderRGBA[2] = 0;
10988                                 break;
10989                         }
10990                 }
10991                 else
10992                 {       // Not a team game
10993                         legs.shaderRGBA[0] = 255;
10994                         legs.shaderRGBA[1] = 255;
10995                         legs.shaderRGBA[2] = 0;
10996                 }
10997 
10998 /*              if (cg.snap->ps.fd.forcePowerLevel[FP_SEE] <= FORCE_LEVEL_1)
10999                 {
11000                         legs.renderfx |= RF_MINLIGHT;
11001                 }
11002                 else
11003 */              {       // See through walls.
11004                         legs.renderfx |= RF_MINLIGHT | RF_NODEPTH;
11005 
11006                         if (cg.snap->ps.fd.forcePowerLevel[FP_SEE] < FORCE_LEVEL_2)
11007                         { //only level 2+ can see players through walls
11008                                 legs.renderfx &= ~RF_NODEPTH;
11009                         }
11010                 }
11011 
11012                 legs.renderfx &= ~RF_RGB_TINT;
11013                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
11014                 legs.customShader = cgs.media.sightShell;
11015                 
11016                 trap_R_AddRefEntityToScene( &legs );
11017         }
11018 
11019         // Electricity
11020         //------------------------------------------------
11021         if ( cent->currentState.emplacedOwner > cg.time ) 
11022         {
11023                 int     dif = cent->currentState.emplacedOwner - cg.time;
11024                 vec3_t tempAngles;
11025 
11026                 if ( dif > 0 && random() > 0.4f )
11027                 {
11028                         // fade out over the last 500 ms
11029                         int brightness = 255;
11030                         
11031                         if ( dif < 500 )
11032                         {
11033                                 brightness = floor((dif - 500.0f) / 500.0f * 255.0f );
11034                         }
11035 
11036                         legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
11037                         legs.renderfx &= ~RF_MINLIGHT;
11038 
11039                         legs.renderfx |= RF_RGB_TINT;
11040                         legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = brightness;
11041                         legs.shaderRGBA[3] = 255;
11042 
11043                         if ( rand() & 1 )
11044                         {
11045                                 legs.customShader = cgs.media.electricBodyShader;       
11046                         }
11047                         else
11048                         {
11049                                 legs.customShader = cgs.media.electricBody2Shader;
11050                         }
11051 
11052                         trap_R_AddRefEntityToScene( &legs );
11053 
11054                         if ( random() > 0.9f )
11055                                 trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, cgs.media.crackleSound );
11056                 }
11057 
11058                 VectorSet(tempAngles, 0, cent->lerpAngles[YAW], 0);
11059                 CG_ForceElectrocution( cent, legs.origin, tempAngles, cgs.media.boltShader, qfalse );
11060         } 
11061 
11062         if (cent->currentState.powerups & (1 << PW_SHIELDHIT))
11063         {
11064                 /*
11065                 legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = 255.0f * 0.5f;//t;
11066                 legs.shaderRGBA[3] = 255;
11067                 legs.renderfx &= ~RF_ALPHA_FADE;
11068                 legs.renderfx |= RF_RGB_TINT;
11069                 */
11070 
11071                 legs.shaderRGBA[0] = legs.shaderRGBA[1] = legs.shaderRGBA[2] = Q_irand(1, 255);
11072 
11073                 legs.renderfx &= ~RF_FORCE_ENT_ALPHA;
11074                 legs.renderfx &= ~RF_MINLIGHT;
11075                 legs.renderfx &= ~RF_RGB_TINT;
11076                 legs.customShader = cgs.media.playerShieldDamage;
11077                 
11078                 trap_R_AddRefEntityToScene( &legs );
11079         }
11080 #if 0
11081 endOfCall:
11082         
11083         if (cgBoneAnglePostSet.refreshSet)
11084         {
11085                 trap_G2API_SetBoneAngles(cgBoneAnglePostSet.ghoul2, cgBoneAnglePostSet.modelIndex, cgBoneAnglePostSet.boneName,
11086                         cgBoneAnglePostSet.angles, cgBoneAnglePostSet.flags, cgBoneAnglePostSet.up, cgBoneAnglePostSet.right,
11087                         cgBoneAnglePostSet.forward, cgBoneAnglePostSet.modelList, cgBoneAnglePostSet.blendTime, cgBoneAnglePostSet.currentTime);
11088 
11089                 cgBoneAnglePostSet.refreshSet = qfalse;
11090         }
11091 #endif
11092 }

void CG_PlayerAnimEventDo centity_t cent,
animevent_t animEvent
 

Definition at line 2237 of file cg_players.c.

References AED_BOLTINDEX, AED_EFFECTINDEX, AED_FOOTSTEP_TYPE, AED_MODELINDEX, AED_SABER_SPIN_SABERNUM, AED_SABER_SPIN_TYPE, AED_SABER_SWING_SABERNUM, AED_SABER_SWING_TYPE, AED_SOUND_NUMRANDOMSNDS, AED_SOUNDCHANNEL, AED_SOUNDINDEX_START, AEV_EFFECT, AEV_FIRE, AEV_FOOTSTEP, AEV_MOVE, AEV_SABER_SPIN, AEV_SABER_SWING, AEV_SOUND, AEV_SOUNDCHAN, animevent_t, centity_t, cg, cgs, CHAN_AUTO, client, cgs_t::clientinfo, entityState_s::clientNum, centity_s::currentState, ET_NPC, entityState_s::eType, animevent_s::eventData, animevent_s::eventType, footstepType_t, G_PlayEffect(), cgs_t::gameModels, centity_s::ghoul2, centity_s::lerpAngles, centity_s::lerpOrigin, centity_s::modelScale, centity_s::npcClient, NULL, entityState_s::number, ORIGIN, entityState_s::pos, Q_irand(), Q_stricmp(), Q_stricmpn(), qfalse, qhandle_t, gclient_s::saber, soundChannel_t, animevent_s::stringData, saberInfo_t::swingSound, cg_t::time, trap_FX_PlayEffectID(), trap_G2API_AddBolt(), trap_G2API_GetBoltMatrix(), trap_S_RegisterSound(), trap_S_StartSound(), trajectory_t::trBase, va(), vec3_t, VectorSet, and YAW.

Referenced by CG_PlayerAnimEvents().

02238 {
02239         soundChannel_t channel = CHAN_AUTO;
02240         clientInfo_t *client = NULL;
02241         qhandle_t swingSound = 0;
02242         qhandle_t spinSound = 0;
02243 
02244         if ( !cent || !animEvent )
02245         {
02246                 return;
02247         }
02248 
02249         switch ( animEvent->eventType )
02250         {
02251         case AEV_SOUNDCHAN:
02252                 channel = (soundChannel_t)animEvent->eventData[AED_SOUNDCHANNEL];
02253         case AEV_SOUND:
02254                 {       // are there variations on the sound?
02255                         const int holdSnd = animEvent->eventData[ AED_SOUNDINDEX_START+Q_irand( 0, animEvent->eventData[AED_SOUND_NUMRANDOMSNDS] ) ];
02256                         if ( holdSnd > 0 )
02257                         {
02258                                 trap_S_StartSound( NULL, cent->currentState.number, channel, holdSnd );
02259                         }
02260                 }
02261                 break;
02262         case AEV_SABER_SWING:
02263                 if (cent->currentState.eType == ET_NPC)
02264                 {
02265                         client = cent->npcClient;
02266                         assert(client);
02267                 }
02268                 else
02269                 {
02270                         client = &cgs.clientinfo[cent->currentState.clientNum];
02271                 }
02272                 if ( client && client->infoValid && client->saber[animEvent->eventData[AED_SABER_SWING_SABERNUM]].swingSound[0] )
02273                 {//custom swing sound
02274                         swingSound = client->saber[0].swingSound[Q_irand(0,2)];
02275                 }
02276                 else
02277                 {
02278                         int             randomSwing = 1;
02279                         switch ( animEvent->eventData[AED_SABER_SWING_TYPE] )
02280                         {
02281                         default:
02282                         case 0://SWING_FAST
02283                                 randomSwing = Q_irand( 1, 3 );
02284                                 break;
02285                         case 1://SWING_MEDIUM
02286                                 randomSwing = Q_irand( 4, 6 );
02287                                 break;
02288                         case 2://SWING_STRONG
02289                                 randomSwing = Q_irand( 7, 9 );
02290                                 break;
02291                         }
02292                         swingSound = trap_S_RegisterSound(va("sound/weapons/saber/saberhup%i.wav", randomSwing));
02293                 }
02294                 trap_S_StartSound(cent->currentState.pos.trBase, cent->currentState.number, CHAN_AUTO, swingSound );
02295                 break;
02296         case AEV_SABER_SPIN:
02297                 if (cent->currentState.eType == ET_NPC)
02298                 {
02299                         client = cent->npcClient;
02300                         assert(client);
02301                 }
02302                 else
02303                 {
02304                         client = &cgs.clientinfo[cent->currentState.clientNum];
02305                 }
02306                 if ( client 
02307                         && client->infoValid 
02308                         && client->saber[AED_SABER_SPIN_SABERNUM].spinSound )
02309                 {//use override
02310                         spinSound = client->saber[AED_SABER_SPIN_SABERNUM].spinSound;
02311                 }
02312                 else
02313                 {
02314                         switch ( animEvent->eventData[AED_SABER_SPIN_TYPE] )
02315                         {
02316                         case 0://saberspinoff
02317                                 spinSound = trap_S_RegisterSound( "sound/weapons/saber/saberspinoff.wav" );
02318                                 break;
02319                         case 1://saberspin
02320                                 spinSound = trap_S_RegisterSound( "sound/weapons/saber/saberspin.wav" );
02321                                 break;
02322                         case 2://saberspin1
02323                                 spinSound = trap_S_RegisterSound( "sound/weapons/saber/saberspin1.wav" );
02324                                 break;
02325                         case 3://saberspin2
02326                                 spinSound = trap_S_RegisterSound( "sound/weapons/saber/saberspin2.wav" );
02327                                 break;
02328                         case 4://saberspin3
02329                                 spinSound = trap_S_RegisterSound( "sound/weapons/saber/saberspin3.wav" );
02330                                 break;
02331                         default://random saberspin1-3
02332                                 spinSound = trap_S_RegisterSound( va( "sound/weapons/saber/saberspin%d.wav", Q_irand(1,3)) );
02333                                 break;
02334                         }
02335                 }
02336                 if ( spinSound )
02337                 {
02338                         trap_S_StartSound( NULL, cent->currentState.clientNum, CHAN_AUTO, spinSound );
02339                 }
02340                 break;
02341         case AEV_FOOTSTEP:
02342                 CG_PlayerFootsteps( cent, (footstepType_t)animEvent->eventData[AED_FOOTSTEP_TYPE] );
02343                 break;
02344         case AEV_EFFECT:
02345 #if 0 //SP method
02346                 //add bolt, play effect
02347                 if ( animEvent->stringData != NULL && cent && cent->gent && cent->gent->ghoul2.size() )
02348                 {//have a bolt name we want to use
02349                         animEvent->eventData[AED_BOLTINDEX] = gi.G2API_AddBolt( &cent->gent->ghoul2[cent->gent->playerModel], animEvent->stringData );
02350                         animEvent->stringData = NULL;//so we don't try to do this again
02351                 }
02352                 if ( animEvent->eventData[AED_BOLTINDEX] != -1 )
02353                 {//have a bolt we want to play the effect on
02354                         G_PlayEffect( animEvent->eventData[AED_EFFECTINDEX], cent->gent->playerModel, animEvent->eventData[AED_BOLTINDEX], cent->currentState.clientNum );
02355                 }
02356                 else
02357                 {//play at origin?  FIXME: maybe allow a fwd/rt/up offset?
02358                         theFxScheduler.PlayEffect( animEvent->eventData[AED_EFFECTINDEX], cent->lerpOrigin, qfalse );
02359                 }
02360 #else //my method
02361                 if (animEvent->stringData && animEvent->stringData[0] && cent && cent->ghoul2)
02362                 {
02363                         animEvent->eventData[AED_MODELINDEX] = 0;
02364                         if ( ( Q_stricmpn( "*blade", animEvent->stringData, 6 ) == 0 
02365                                         || Q_stricmp( "*flash", animEvent->stringData ) == 0 ) )
02366                         {//must be a weapon, try weapon 0?
02367                                 animEvent->eventData[AED_BOLTINDEX] = trap_G2API_AddBolt( cent->ghoul2, 1, animEvent->stringData );
02368                                 if ( animEvent->eventData[AED_BOLTINDEX] != -1 )
02369                                 {//found it!
02370                                         animEvent->eventData[AED_MODELINDEX] = 1;
02371                                 }
02372                                 else
02373                                 {//hmm, just try on the player model, then?
02374                                         animEvent->eventData[AED_BOLTINDEX] = trap_G2API_AddBolt( cent->ghoul2, 0, animEvent->stringData );
02375                                 }
02376                         }
02377                         else
02378                         {
02379                                 animEvent->eventData[AED_BOLTINDEX] = trap_G2API_AddBolt( cent->ghoul2, 0, animEvent->stringData );
02380                         }
02381                         animEvent->stringData[0] = 0;
02382                 }
02383                 if ( animEvent->eventData[AED_BOLTINDEX] != -1 )
02384                 {
02385                         vec3_t lAngles;
02386                         vec3_t bPoint, bAngle;
02387                         mdxaBone_t matrix;
02388 
02389                         VectorSet(lAngles, 0, cent->lerpAngles[YAW], 0);
02390 
02391                         trap_G2API_GetBoltMatrix(cent->ghoul2, animEvent->eventData[AED_MODELINDEX], animEvent->eventData[AED_BOLTINDEX], &matrix, lAngles,
02392                                 cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
02393                         BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, bPoint);
02394                         VectorSet(bAngle, 0, 1, 0);
02395 
02396                         trap_FX_PlayEffectID(animEvent->eventData[AED_EFFECTINDEX], bPoint, bAngle, -1, -1);
02397                 }
02398                 else
02399                 {
02400                         vec3_t bAngle;
02401 
02402                         VectorSet(bAngle, 0, 1, 0);
02403                         trap_FX_PlayEffectID(animEvent->eventData[AED_EFFECTINDEX], cent->lerpOrigin, bAngle, -1, -1);
02404                 }
02405 #endif
02406                 break;
02407         //Would have to keep track of this on server to for these, it's not worth it.
02408         case AEV_FIRE:
02409         case AEV_MOVE:
02410                 break;
02411                 /*
02412         case AEV_FIRE:
02413                 //add fire event
02414                 if ( animEvent->eventData[AED_FIRE_ALT] )
02415                 {
02416                         G_AddEvent( cent->gent, EV_ALT_FIRE, 0 );
02417                 }
02418                 else
02419                 {
02420                         G_AddEvent( cent->gent, EV_FIRE_WEAPON, 0 );
02421                 }
02422                 break;
02423         case AEV_MOVE:
02424                 //make him jump
02425                 if ( cent && cent->gent && cent->gent->client )
02426                 {
02427                         if ( cent->gent->client->ps.groundEntityNum != ENTITYNUM_NONE )
02428                         {//on something
02429                                 vec3_t  fwd, rt, up, angles = {0, cent->gent->client->ps.viewangles[YAW], 0};
02430                                 AngleVectors( angles, fwd, rt, up );
02431                                 //FIXME: set or add to velocity?
02432                                 VectorScale( fwd, animEvent->eventData[AED_MOVE_FWD], cent->gent->client->ps.velocity );
02433                                 VectorMA( cent->gent->client->ps.velocity, animEvent->eventData[AED_MOVE_RT], rt, cent->gent->client->ps.velocity );
02434                                 VectorMA( cent->gent->client->ps.velocity, animEvent->eventData[AED_MOVE_UP], up, cent->gent->client->ps.velocity );
02435                                 
02436                                 if ( animEvent->eventData[AED_MOVE_UP] > 0 )
02437                                 {//a jump
02438                                         cent->gent->client->ps.pm_flags |= PMF_JUMPING;
02439 
02440                                         G_AddEvent( cent->gent, EV_JUMP, 0 );
02441                                         //FIXME: if have force jump, do this?  or specify sound in the event data?
02442                                         //cent->gent->client->ps.forceJumpZStart = cent->gent->client->ps.origin[2];//so we don't take damage if we land at same height
02443                                         //G_SoundOnEnt( cent->gent, CHAN_BODY, "sound/weapons/force/jump.wav" );
02444                                 }
02445                         }
02446                 }
02447                 break;
02448                 */
02449         default:
02450                 return;
02451                 break;
02452         }
02453 }

void CG_PlayerAnimEvents int  animFileIndex,
int  eventFileIndex,
qboolean  torso,
int  oldFrame,
int  frame,
int  entNum
 

Definition at line 2461 of file cg_players.c.

References AED_EFFECT_PROBABILITY, AED_FIRE_PROBABILITY, AED_FOOTSTEP_PROBABILITY, AED_SABER_SPIN_PROBABILITY, AED_SABER_SWING_PROBABILITY, AED_SOUND_PROBABILITY, AEV_EFFECT, AEV_FIRE, AEV_FOOTSTEP, AEV_MOVE, AEV_NONE, AEV_SABER_SPIN, AEV_SABER_SWING, AEV_SOUND, AEV_SOUNDCHAN, animation_t, animevent_t, bgLoadedAnim_t::anims, bgAllAnims, bgAllEvents, cg_entities, CG_PlayerAnimEventDo(), centity_s::currentState, animevent_s::eventData, animevent_s::eventType, fabs(), animation_s::firstFrame, animation_s::frameLerp, animevent_s::keyFrame, entityState_s::legsAnim, bgLoadedEvents_t::legsAnimEvents, animation_s::loopFrames, MAX_ANIM_EVENTS, centity_s::nextState, NULL, animation_s::numFrames, Q_irand(), qboolean, qfalse, qtrue, entityState_s::torsoAnim, and bgLoadedEvents_t::torsoAnimEvents.

Referenced by CG_TriggerAnimSounds().

02462 {
02463         int             i;
02464         int             firstFrame = 0, lastFrame = 0;
02465         qboolean        doEvent = qfalse, inSameAnim = qfalse, loopAnim = qfalse, match = qfalse, animBackward = qfalse;
02466         animevent_t *animEvents = NULL;
02467         
02468         if ( torso )
02469         {
02470                 animEvents = bgAllEvents[eventFileIndex].torsoAnimEvents;
02471         }
02472         else
02473         {
02474                 animEvents = bgAllEvents[eventFileIndex].legsAnimEvents;
02475         }
02476         if ( fabs((float)(oldFrame-frame)) > 1 )
02477         {//given a range, see if keyFrame falls in that range
02478                 int oldAnim, anim;
02479                 if ( torso )
02480                 {
02481                         /*
02482                         if ( cg_reliableAnimSounds.integer > 1 )
02483                         {//more precise, slower
02484                                 oldAnim = PM_TorsoAnimForFrame( &g_entities[entNum], oldFrame );
02485                                 anim = PM_TorsoAnimForFrame( &g_entities[entNum], frame );
02486                         }
02487                         else
02488                         */
02489                         {//less precise, but faster
02490                                 oldAnim = cg_entities[entNum].currentState.torsoAnim;
02491                                 anim = cg_entities[entNum].nextState.torsoAnim;
02492                         }
02493                 }
02494                 else
02495                 {
02496                         /*
02497                         if ( cg_reliableAnimSounds.integer > 1 )
02498                         {//more precise, slower
02499                                 oldAnim = PM_LegsAnimForFrame( &g_entities[entNum], oldFrame );
02500                                 anim = PM_TorsoAnimForFrame( &g_entities[entNum], frame );
02501                         }
02502                         else
02503                         */
02504                         {//less precise, but faster
02505                                 oldAnim = cg_entities[entNum].currentState.legsAnim;
02506                                 anim = cg_entities[entNum].nextState.legsAnim;
02507                         }
02508                 }
02509                 if ( anim != oldAnim )
02510                 {//not in same anim
02511                         inSameAnim = qfalse;
02512                         //FIXME: we *could* see if the oldFrame was *just about* to play the keyframed sound...
02513                 }
02514                 else
02515                 {//still in same anim, check for looping anim
02516                         animation_t *animation;
02517 
02518                         inSameAnim = qtrue;
02519                         animation = &bgAllAnims[animFileIndex].anims[anim];
02520                         animBackward = (animation->frameLerp<0);
02521                         if ( animation->loopFrames != -1 )
02522                         {//a looping anim!
02523                                 loopAnim = qtrue;
02524                                 firstFrame = animation->firstFrame;
02525                                 lastFrame = animation->firstFrame+animation->numFrames;
02526                         }
02527                 }
02528         }
02529 
02530         // Check for anim sound
02531         for (i=0;i<MAX_ANIM_EVENTS;++i)
02532         {
02533                 if ( animEvents[i].eventType == AEV_NONE )      // No event, end of list
02534                 {
02535                         break;
02536                 }
02537 
02538                 match = qfalse;
02539                 if ( animEvents[i].keyFrame == frame )
02540                 {//exact match
02541                         match = qtrue;
02542                 }
02543                 else if ( fabs((float)(oldFrame-frame)) > 1 /*&& cg_reliableAnimSounds.integer*/ )
02544                 {//given a range, see if keyFrame falls in that range
02545                         if ( inSameAnim )
02546                         {//if changed anims altogether, sorry, the sound is lost
02547                                 if ( fabs((float)(oldFrame-animEvents[i].keyFrame)) <= 3
02548                                          || fabs((float)(frame-animEvents[i].keyFrame)) <= 3 )
02549                                 {//must be at least close to the keyframe
02550                                         if ( animBackward )
02551                                         {//animation plays backwards
02552                                                 if ( oldFrame > animEvents[i].keyFrame && frame < animEvents[i].keyFrame )
02553                                                 {//old to new passed through keyframe
02554                                                         match = qtrue;
02555                                                 }
02556                                                 else if ( loopAnim )
02557                                                 {//hmm, didn't pass through it linearally, see if we looped
02558                                                         if ( animEvents[i].keyFrame >= firstFrame && animEvents[i].keyFrame < lastFrame )
02559                                                         {//keyframe is in this anim
02560                                                                 if ( oldFrame > animEvents[i].keyFrame 
02561                                                                         && frame > oldFrame )
02562                                                                 {//old to new passed through keyframe
02563                                                                         match = qtrue;
02564                                                                 }
02565                                                         }
02566                                                 }
02567                                         }
02568                                         else
02569                                         {//anim plays forwards
02570                                                 if ( oldFrame < animEvents[i].keyFrame && frame > animEvents[i].keyFrame )
02571                                                 {//old to new passed through keyframe
02572                                                         match = qtrue;
02573                                                 }
02574                                                 else if ( loopAnim )
02575                                                 {//hmm, didn't pass through it linearally, see if we looped
02576                                                         if ( animEvents[i].keyFrame >= firstFrame && animEvents[i].keyFrame < lastFrame )
02577                                                         {//keyframe is in this anim
02578                                                                 if ( oldFrame < animEvents[i].keyFrame 
02579                                                                         && frame < oldFrame )
02580                                                                 {//old to new passed through keyframe
02581                                                                         match = qtrue;
02582                                                                 }
02583                                                         }
02584                                                 }
02585                                         }
02586                                 }
02587                         }
02588                 }
02589                 if ( match )
02590                 {
02591                         switch ( animEvents[i].eventType )
02592                         {
02593                         case AEV_SOUND:
02594                         case AEV_SOUNDCHAN:
02595                                 // Determine probability of playing sound
02596                                 if (!animEvents[i].eventData[AED_SOUND_PROBABILITY])    // 100% 
02597                                 {
02598                                         doEvent = qtrue;
02599                                 }
02600                                 else if (animEvents[i].eventData[AED_SOUND_PROBABILITY] > Q_irand(0, 99) )
02601                                 {
02602                                         doEvent = qtrue;
02603                                 }
02604                                 break;
02605                         case AEV_SABER_SWING:
02606                                 // Determine probability of playing sound
02607                                 if (!animEvents[i].eventData[AED_SABER_SWING_PROBABILITY])      // 100% 
02608                                 {
02609                                         doEvent = qtrue;
02610                                 }
02611                                 else if (animEvents[i].eventData[AED_SABER_SWING_PROBABILITY] > Q_irand(0, 99) )
02612                                 {
02613                                         doEvent = qtrue;
02614                                 }
02615                                 break;
02616                         case AEV_SABER_SPIN:
02617                                 // Determine probability of playing sound
02618                                 if (!animEvents[i].eventData[AED_SABER_SPIN_PROBABILITY])       // 100% 
02619                                 {
02620                                         doEvent = qtrue;
02621                                 }
02622                                 else if (animEvents[i].eventData[AED_SABER_SPIN_PROBABILITY] > Q_irand(0, 99) )
02623                                 {
02624                                         doEvent = qtrue;
02625                                 }
02626                                 break;
02627                         case AEV_FOOTSTEP:
02628                                 // Determine probability of playing sound
02629                                 if (!animEvents[i].eventData[AED_FOOTSTEP_PROBABILITY]) // 100% 
02630                                 {
02631                                         doEvent = qtrue;
02632                                 }
02633                                 else if (animEvents[i].eventData[AED_FOOTSTEP_PROBABILITY] > Q_irand(0, 99) )
02634                                 {
02635                                         doEvent = qtrue;
02636                                 }
02637                                 break;
02638                         case AEV_EFFECT:
02639                                 // Determine probability of playing sound
02640                                 if (!animEvents[i].eventData[AED_EFFECT_PROBABILITY])   // 100% 
02641                                 {
02642                                         doEvent = qtrue;
02643                                 }
02644                                 else if (animEvents[i].eventData[AED_EFFECT_PROBABILITY] > Q_irand(0, 99) )
02645                                 {
02646                                         doEvent = qtrue;
02647                                 }
02648                                 break;
02649                         case AEV_FIRE:
02650                                 // Determine probability of playing sound
02651                                 if (!animEvents[i].eventData[AED_FIRE_PROBABILITY])     // 100% 
02652                                 {
02653                                         doEvent = qtrue;
02654                                 }
02655                                 else if (animEvents[i].eventData[AED_FIRE_PROBABILITY] > Q_irand(0, 99) )
02656                                 {
02657                                         doEvent = qtrue;
02658                                 }
02659                                 break;
02660                         case AEV_MOVE:
02661                                 doEvent = qtrue;
02662                                 break;
02663                         default:
02664                                 //doEvent = qfalse;//implicit
02665                                 break;
02666                         }
02667                         // do event
02668                         if ( doEvent )
02669                         {
02670                                 CG_PlayerAnimEventDo( &cg_entities[entNum], &animEvents[i] );
02671                         }
02672                 }
02673         }
02674 }

void CG_PlayerHitFX centity_t cent  ) 
 

Definition at line 5145 of file cg_players.c.

References centity_t, cg, CG_DrawPlayerShield(), CLASS_VEHICLE, playerState_s::clientNum, entityState_s::clientNum, centity_s::currentState, centity_s::damageTime, centity_s::lerpOrigin, entityState_s::NPC_class, cg_t::predictedPlayerState, cg_t::renderingThirdPerson, and cg_t::time.

Referenced by CG_Player().

05146 {
05147         // only do the below fx if the cent in question is...uh...me, and it's first person.
05148         if (cent->currentState.clientNum != cg.predictedPlayerState.clientNum || cg.renderingThirdPerson)
05149         {
05150                 if (cent->damageTime > cg.time
05151                         && cent->currentState.NPC_class != CLASS_VEHICLE )
05152                 {
05153                         CG_DrawPlayerShield(cent, cent->lerpOrigin);
05154                 }
05155 
05156                 return;
05157         }
05158 }

void CG_PlayerShieldHit int  entitynum,
vec3_t  dir,
int  amount
 

Definition at line 5077 of file cg_players.c.

References centity_t, cg, cg_entities, centity_s::damageAngles, centity_s::damageTime, MAX_ENTITIES, MAX_SHIELD_TIME, cg_t::time, vec3_t, vectoangles(), and VectorScale.

Referenced by CG_EntityEvent().

05078 {
05079         centity_t *cent;
05080         int     time;
05081 
05082         if (entitynum<0 || entitynum >= MAX_ENTITIES)
05083         {
05084                 return;
05085         }
05086 
05087         cent = &cg_entities[entitynum];
05088 
05089         if (amount > 100)
05090         {
05091                 time = cg.time + MAX_SHIELD_TIME;               // 2 sec.
05092         }
05093         else
05094         {
05095                 time = cg.time + 500 + amount*15;
05096         }
05097 
05098         if (time > cent->damageTime)
05099         {
05100                 cent->damageTime = time;
05101                 VectorScale(dir, -1, dir);
05102                 vectoangles(dir, cent->damageAngles);
05103         }
05104 }

float CG_RadiusForCent centity_t cent  ) 
 

Definition at line 8301 of file cg_players.c.

References centity_t, CLASS_VEHICLE, centity_s::currentState, ET_NPC, entityState_s::eType, entityState_s::g2radius, vehicleInfo_t::g2radius, centity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, and entityState_s::NPC_class.

Referenced by CG_DrawBracketedEntities(), and CG_Player().

08302 {
08303         if ( cent->currentState.eType == ET_NPC )
08304         {
08305                 if (cent->currentState.NPC_class == CLASS_VEHICLE &&
08306                         cent->m_pVehicle &&
08307                         cent->m_pVehicle->m_pVehicleInfo->g2radius)
08308                 { //has override
08309                         return cent->m_pVehicle->m_pVehicleInfo->g2radius;
08310                 }
08311                 else if ( cent->currentState.g2radius )
08312                 {
08313                         return cent->currentState.g2radius;
08314                 }
08315         }
08316         else if ( cent->currentState.g2radius )
08317         {
08318                 return cent->currentState.g2radius;
08319         }
08320         return 64.0f;
08321 }

void CG_Rag_Trace trace_t result,
const vec3_t  start,
const vec3_t  mins,
const vec3_t  maxs,
const vec3_t  end,
int  skipNumber,
int  mask
 

Definition at line 3407 of file cg_players.c.

References trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, trace_t::fraction, trap_CM_BoxTrace(), and vec3_t.

Referenced by CG_RagDoll().

03408                                                                     {
03409         trap_CM_BoxTrace ( result, start, end, mins, maxs, 0, mask);
03410         result->entityNum = result->fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
03411 }

qboolean CG_RagDoll centity_t cent,
vec3_t  forcedAngles
 

Definition at line 3486 of file cg_players.c.

References trace_t::allsolid, sharedRagDollUpdateParams_t::angles, sharedRagDollParams_t::angles, animation_t, lerpFrame_t::animationTime, bgAllAnims, BONE_ANGLES_POSTMULT, BONE_ANIM_OVERRIDE_LOOP, centity_t, cg, cg_entities, CG_G2SetBoneAngles(), CG_Rag_Trace(), cg_ragDoll, CG_TestLine(), cgs, CLASS_VEHICLE, sharedRagDollParams_t::collisionType, centity_s::currentState, EF_RAG, entityState_s::eFlags, sharedRagDollParams_t::endFrame, ENTITYNUM_NONE, ET_BODY, ET_NPC, entityState_s::eType, fabs(), animation_s::firstFrame, flrand(), trace_t::fraction, sharedRagDollParams_t::fShotStrength, cgs_t::gameModels, centity_s::ghoul2, entityState_s::groundEntityNum, IKS_NONE, centity_s::ikStatus, vmCvar_t::integer, centity_s::isRagging, playerEntity_t::legs, entityState_s::legsAnim, centity_s::lerpAngles, centity_s::lerpOrigin, centity_s::localAnimIndex, MASK_SOLID, sharedRagDollUpdateParams_t::me, sharedRagDollParams_t::me, centity_s::modelScale, NEGATIVE_Y, NEGATIVE_Z, entityState_s::NPC_class, NULL, entityState_s::number, animation_s::numFrames, ORIGIN, centity_s::overridingBones, centity_s::ownerRagging, centity_s::pe, PITCH, entityState_s::pos, sharedRagDollUpdateParams_t::position, sharedRagDollParams_t::position, POSITIVE_X, qboolean, qfalse, qtrue, entityState_s::ragAttach, centity_s::ragLastOrigin, centity_s::ragLastOriginTime, sharedRagDollParams_t::RagPhase, ROLL, RP_DEATH_COLLISION, sharedRagDollUpdateParams_t::scale, sharedRagDollParams_t::scale, sharedRagDollUpdateParams_t::settleFrame, sharedRagDollParams_t::startFrame, trace_t::startsolid, cg_t::time, playerEntity_t::torso, trap_G2API_AddBolt(), trap_G2API_AnimateG2Models(), trap_G2API_GetBoltMatrix(), trap_G2API_GetBoneAnim(), trap_G2API_RagEffectorGoal(), trap_G2API_RagEffectorKick(), trap_G2API_RagForceSolve(), trap_G2API_RagPCJConstraint(), trap_G2API_RagPCJGradientSpeed(), trap_G2API_SetBoneAnim(), trap_G2API_SetBoneIKState(), trap_G2API_SetRagDoll(), trajectory_t::trDelta, centity_s::turAngles, vec3_origin, vec3_t, vectoangles(), VectorAdd, VectorClear, VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSet, VectorSubtract, sharedRagDollUpdateParams_t::velocity, YAW, and lerpFrame_t::yawAngle.

Referenced by CG_G2Animated().

03487 {
03488         vec3_t usedOrg;
03489         qboolean inSomething = qfalse;
03490         int ragAnim;//BOTH_DEAD1; //BOTH_DEATH1;
03491 
03492         if (!cg_ragDoll.integer)
03493         {
03494                 return qfalse;
03495         }
03496 
03497         if (cent->localAnimIndex)
03498         { //don't rag non-humanoids
03499                 return qfalse;
03500         }
03501 
03502         VectorCopy(cent->lerpOrigin, usedOrg);
03503 
03504         if (!cent->isRagging)
03505         { //If we're not in a ragdoll state, perform the checks.
03506                 if (cent->currentState.eFlags & EF_RAG)
03507                 { //want to go into it no matter what then
03508                         inSomething = qtrue;
03509                 }
03510                 else if (cent->currentState.groundEntityNum == ENTITYNUM_NONE)
03511                 {
03512                         vec3_t cVel;
03513 
03514                         VectorCopy(cent->currentState.pos.trDelta, cVel);
03515 
03516                         if (VectorNormalize(cVel) > 400)
03517                         { //if he's flying through the air at a good enough speed, switch into ragdoll
03518                                 inSomething = qtrue;
03519                         }
03520                 }
03521 
03522                 if (cent->currentState.eType == ET_BODY)
03523                 { //just rag bodies immediately if their own was ragging on respawn
03524                         if (cent->ownerRagging)
03525                         {
03526                                 cent->isRagging = qtrue;
03527                                 return qfalse;
03528                         }
03529                 }
03530 
03531                 if (cg_ragDoll.integer > 1)
03532                 {
03533                         inSomething = qtrue;
03534                 }
03535 
03536                 if (!inSomething)
03537                 {
03538                         int anim = (cent->currentState.legsAnim);
03539                         int dur = (bgAllAnims[cent->localAnimIndex].anims[anim].numFrames-1) * fabs((float)(bgAllAnims[cent->localAnimIndex].anims[anim].frameLerp));
03540                         int i = 0;
03541                         int boltChecks[5];
03542                         vec3_t boltPoints[5];
03543                         vec3_t trStart, trEnd;
03544                         vec3_t tAng;
03545                         qboolean deathDone = qfalse;
03546                         trace_t tr;
03547                         mdxaBone_t boltMatrix;
03548 
03549                         VectorSet( tAng, cent->turAngles[PITCH], cent->turAngles[YAW], cent->turAngles[ROLL] );
03550 
03551                         if (cent->pe.legs.animationTime > 50 && (cg.time - cent->pe.legs.animationTime) > dur)
03552                         { //Looks like the death anim is done playing
03553                                 deathDone = qtrue;
03554                         }
03555 
03556                         if (deathDone)
03557                         { //only trace from the hands if the death anim is already done.
03558                                 boltChecks[0] = trap_G2API_AddBolt(cent->ghoul2, 0, "rhand");
03559                                 boltChecks[1] = trap_G2API_AddBolt(cent->ghoul2, 0, "lhand");
03560                         }
03561                         else
03562                         { //otherwise start the trace loop at the cranium.
03563                                 i = 2;
03564                         }
03565                         boltChecks[2] = trap_G2API_AddBolt(cent->ghoul2, 0, "cranium");
03566                         //boltChecks[3] = trap_G2API_AddBolt(cent->ghoul2, 0, "rtarsal");
03567                         //boltChecks[4] = trap_G2API_AddBolt(cent->ghoul2, 0, "ltarsal");
03568                         boltChecks[3] = trap_G2API_AddBolt(cent->ghoul2, 0, "rtalus");
03569                         boltChecks[4] = trap_G2API_AddBolt(cent->ghoul2, 0, "ltalus");
03570 
03571                         //This may seem bad, but since we have a bone cache now it should manage to not be too disgustingly slow.
03572                         //Do the head first, because the hands reference it anyway.
03573                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, boltChecks[2], &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
03574                         BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltPoints[2]);
03575 
03576                         while (i < 5)
03577                         {
03578                                 if (i < 2)
03579                                 { //when doing hands, trace to the head instead of origin
03580                                         trap_G2API_GetBoltMatrix(cent->ghoul2, 0, boltChecks[i], &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
03581                                         BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltPoints[i]);
03582                                         VectorCopy(boltPoints[i], trStart);
03583                                         VectorCopy(boltPoints[2], trEnd);
03584                                 }
03585                                 else
03586                                 {
03587                                         if (i > 2)
03588                                         { //2 is the head, which already has the bolt point.
03589                                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, boltChecks[i], &boltMatrix, tAng, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
03590                                                 BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltPoints[i]);
03591                                         }
03592                                         VectorCopy(boltPoints[i], trStart);
03593                                         VectorCopy(cent->lerpOrigin, trEnd);
03594                                 }
03595 
03596                                 //Now that we have all that sorted out, trace between the two points we desire.
03597                                 CG_Rag_Trace(&tr, trStart, NULL, NULL, trEnd, cent->currentState.number, MASK_SOLID);
03598 
03599                                 if (tr.fraction != 1.0 || tr.startsolid || tr.allsolid)
03600                                 { //Hit something or start in solid, so flag it and break.
03601                                         //This is a slight hack, but if we aren't done with the death anim, we don't really want to
03602                                         //go into ragdoll unless our body has a relatively "flat" pitch.
03603 #if 0
03604                                         vec3_t vSub;
03605 
03606                                         //Check the pitch from the head to the right foot (should be reasonable)
03607                                         VectorSubtract(boltPoints[2], boltPoints[3], vSub);
03608                                         VectorNormalize(vSub);
03609                                         vectoangles(vSub, vSub);
03610 
03611                                         if (deathDone || (vSub[PITCH] < 50 && vSub[PITCH] > -50))
03612                                         {
03613                                                 inSomething = qtrue;
03614                                         }
03615 #else
03616                                         inSomething = qtrue;
03617 #endif
03618                                         break;
03619                                 }
03620 
03621                                 i++;
03622                         }
03623                 }
03624 
03625                 if (inSomething)
03626                 {
03627                         cent->isRagging = qtrue;
03628 #if 0
03629                         VectorClear(cent->lerpOriginOffset);
03630 #endif
03631                 }
03632         }
03633 
03634         if (cent->isRagging)
03635         { //We're in a ragdoll state, so make the call to keep our positions updated and whatnot.
03636                 sharedRagDollParams_t tParms;
03637                 sharedRagDollUpdateParams_t tuParms;
03638 
03639                 ragAnim = CG_RagAnimForPositioning(cent);
03640 
03641                 if (cent->ikStatus)
03642                 { //ik must be reset before ragdoll is started, or you'll get some interesting results.
03643                         trap_G2API_SetBoneIKState(cent->ghoul2, cg.time, NULL, IKS_NONE, NULL);
03644                         cent->ikStatus = qfalse;
03645                 }
03646 
03647                 //these will be used as "base" frames for the ragoll settling.
03648                 tParms.startFrame = bgAllAnims[cent->localAnimIndex].anims[ragAnim].firstFrame;// + bgAllAnims[cent->localAnimIndex].anims[ragAnim].numFrames;
03649                 tParms.endFrame = bgAllAnims[cent->localAnimIndex].anims[ragAnim].firstFrame + bgAllAnims[cent->localAnimIndex].anims[ragAnim].numFrames;
03650 #if 0
03651                 {
03652                         float animSpeed = 0;
03653                         int blendTime = 600;
03654                         int flags = 0;//BONE_ANIM_OVERRIDE_FREEZE;
03655 
03656                         if (bgAllAnims[cent->localAnimIndex].anims[ragAnim].loopFrames != -1)
03657                         {
03658                                 flags = BONE_ANIM_OVERRIDE_LOOP;
03659                         }
03660 
03661                         /*
03662                         if (cg_animBlend.integer)
03663                         {
03664                                 flags |= BONE_ANIM_BLEND;
03665                         }
03666                         */
03667 
03668                         animSpeed = 50.0f / bgAllAnims[cent->localAnimIndex].anims[ragAnim].frameLerp;
03669                         trap_G2API_SetBoneAnim(cent->ghoul2, 0, "lower_lumbar", tParms.startFrame, tParms.endFrame, flags, animSpeed,cg.time, -1, blendTime);
03670                         trap_G2API_SetBoneAnim(cent->ghoul2, 0, "Motion", tParms.startFrame, tParms.endFrame, flags, animSpeed, cg.time, -1, blendTime);
03671                         trap_G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", tParms.startFrame, tParms.endFrame, flags, animSpeed, cg.time, -1, blendTime);
03672                 }
03673 #elif 1 //with my new method of doing things I want it to continue the anim
03674                 {
03675                         float currentFrame;
03676                         int startFrame, endFrame;
03677                         int flags;
03678                         float animSpeed;
03679 
03680                         if (trap_G2API_GetBoneAnim(cent->ghoul2, "model_root", cg.time, &currentFrame, &startFrame, &endFrame, &flags, &animSpeed, cgs.gameModels, 0))
03681                         { //lock the anim on the current frame.
03682                                 int blendTime = 500;
03683                                 animation_t *curAnim = &bgAllAnims[cent->localAnimIndex].anims[cent->currentState.legsAnim];
03684 
03685                                 if (currentFrame >= (curAnim->firstFrame + curAnim->numFrames-1))
03686                                 { //this is sort of silly but it works for now.
03687                                         currentFrame = (curAnim->firstFrame + curAnim->numFrames-2);
03688                                 }
03689 
03690                                 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "lower_lumbar", currentFrame, currentFrame+1, flags, animSpeed,cg.time, currentFrame, blendTime);
03691                                 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", currentFrame, currentFrame+1, flags, animSpeed, cg.time, currentFrame, blendTime);
03692                                 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "Motion", currentFrame, currentFrame+1, flags, animSpeed, cg.time, currentFrame, blendTime);
03693                         }
03694                 }
03695 #endif
03696                 CG_G2SetBoneAngles(cent->ghoul2, 0, "upper_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
03697                 CG_G2SetBoneAngles(cent->ghoul2, 0, "lower_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
03698                 CG_G2SetBoneAngles(cent->ghoul2, 0, "thoracic", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
03699                 CG_G2SetBoneAngles(cent->ghoul2, 0, "cervical", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
03700 
03701                 VectorCopy(forcedAngles, tParms.angles);
03702                 VectorCopy(usedOrg, tParms.position);
03703                 VectorCopy(cent->modelScale, tParms.scale);
03704                 tParms.me = cent->currentState.number;
03705 
03706                 tParms.collisionType = 1;
03707                 tParms.RagPhase = RP_DEATH_COLLISION;
03708                 tParms.fShotStrength = 4;
03709 
03710                 trap_G2API_SetRagDoll(cent->ghoul2, &tParms);
03711 
03712                 VectorCopy(forcedAngles, tuParms.angles);
03713                 VectorCopy(usedOrg, tuParms.position);
03714                 VectorCopy(cent->modelScale, tuParms.scale);
03715                 tuParms.me = cent->currentState.number;
03716                 tuParms.settleFrame = tParms.endFrame-1;
03717 
03718                 if (cent->currentState.groundEntityNum != ENTITYNUM_NONE)
03719                 {
03720                         VectorClear(tuParms.velocity);
03721                 }
03722                 else
03723                 {
03724                         VectorScale(cent->currentState.pos.trDelta, 2.0f, tuParms.velocity);
03725                 }
03726 
03727                 trap_G2API_AnimateG2Models(cent->ghoul2, cg.time, &tuParms);
03728 
03729                 //So if we try to get a bolt point it's still correct
03730                 cent->turAngles[YAW] = 
03731                 cent->lerpAngles[YAW] = 
03732                 cent->pe.torso.yawAngle = 
03733                 cent->pe.legs.yawAngle = forcedAngles[YAW];
03734 
03735                 if (cent->currentState.ragAttach &&
03736                         (cent->currentState.eType != ET_NPC || cent->currentState.NPC_class != CLASS_VEHICLE))
03737                 {
03738                         centity_t *grabEnt;
03739 
03740                         if (cent->currentState.ragAttach == ENTITYNUM_NONE)
03741                         { //switch cl 0 and entitynum_none, so we can operate on the "if non-0" concept
03742                                 grabEnt = &cg_entities[0];
03743                         }
03744                         else
03745                         {
03746                                 grabEnt = &cg_entities[cent->currentState.ragAttach];
03747                         }
03748 
03749                         if (grabEnt->ghoul2)
03750                         {
03751                                 mdxaBone_t matrix;
03752                                 vec3_t bOrg;
03753                                 vec3_t thisHand;
03754                                 vec3_t hands;
03755                                 vec3_t pcjMin, pcjMax;
03756                                 vec3_t pDif;
03757                                 vec3_t thorPoint;
03758                                 float difLen;
03759                                 int thorBolt;
03760 
03761                                 //Get the person who is holding our hand's hand location
03762                                 trap_G2API_GetBoltMatrix(grabEnt->ghoul2, 0, 0, &matrix, grabEnt->turAngles, grabEnt->lerpOrigin,
03763                                         cg.time, cgs.gameModels, grabEnt->modelScale);
03764                                 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, bOrg);
03765 
03766                                 //Get our hand's location
03767                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, 0, &matrix, cent->turAngles, cent->lerpOrigin,
03768                                         cg.time, cgs.gameModels, cent->modelScale);
03769                                 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, thisHand);
03770 
03771                                 //Get the position of the thoracic bone for hinting its velocity later on
03772                                 thorBolt = trap_G2API_AddBolt(cent->ghoul2, 0, "thoracic");
03773                                 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, thorBolt, &matrix, cent->turAngles, cent->lerpOrigin,
03774                                         cg.time, cgs.gameModels, cent->modelScale);
03775                                 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, thorPoint);
03776 
03777                                 VectorSubtract(bOrg, thisHand, hands);
03778 
03779                                 if (VectorLength(hands) < 3.0f)
03780                                 {
03781                                         trap_G2API_RagForceSolve(cent->ghoul2, qfalse);
03782                                 }
03783                                 else
03784                                 {
03785                                         trap_G2API_RagForceSolve(cent->ghoul2, qtrue);
03786                                 }
03787 
03788                                 //got the hand pos of him, now we want to make our hand go to it
03789                                 trap_G2API_RagEffectorGoal(cent->ghoul2, "rhand", bOrg);
03790                                 trap_G2API_RagEffectorGoal(cent->ghoul2, "rradius", bOrg);
03791                                 trap_G2API_RagEffectorGoal(cent->ghoul2, "rradiusX", bOrg);
03792                                 trap_G2API_RagEffectorGoal(cent->ghoul2, "rhumerusX", bOrg);
03793                                 trap_G2API_RagEffectorGoal(cent->ghoul2, "rhumerus", bOrg);
03794 
03795                                 //Make these two solve quickly so we can update decently
03796                                 trap_G2API_RagPCJGradientSpeed(cent->ghoul2, "rhumerus", 1.5f);
03797                                 trap_G2API_RagPCJGradientSpeed(cent->ghoul2, "rradius", 1.5f);
03798 
03799                                 //Break the constraints on them I suppose
03800                                 VectorSet(pcjMin, -999, -999, -999);
03801                                 VectorSet(pcjMax, 999, 999, 999);
03802                                 trap_G2API_RagPCJConstraint(cent->ghoul2, "rhumerus", pcjMin, pcjMax);
03803                                 trap_G2API_RagPCJConstraint(cent->ghoul2, "rradius", pcjMin, pcjMax);
03804 
03805                                 cent->overridingBones = cg.time + 2000;
03806 
03807                                 //hit the thoracic velocity to the hand point
03808                                 VectorSubtract(bOrg, thorPoint, hands);
03809                                 VectorNormalize(hands);
03810                                 VectorScale(hands, 2048.0f, hands);
03811                                 trap_G2API_RagEffectorKick(cent->ghoul2, "thoracic", hands);
03812                                 trap_G2API_RagEffectorKick(cent->ghoul2, "ceyebrow", hands);
03813 
03814                                 VectorSubtract(cent->ragLastOrigin, cent->lerpOrigin, pDif);
03815                                 VectorCopy(cent->lerpOrigin, cent->ragLastOrigin);
03816 
03817                                 if (cent->ragLastOriginTime >= cg.time && cent->currentState.groundEntityNum != ENTITYNUM_NONE)
03818                                 { //make sure it's reasonably updated
03819                                         difLen = VectorLength(pDif);
03820                                         if (difLen > 0.0f)
03821                                         { //if we're being dragged, then kick all the bones around a bit
03822                                                 vec3_t dVel;
03823                                                 vec3_t rVel;
03824                                                 int i = 0;
03825 
03826                                                 if (difLen < 12.0f)
03827                                                 {
03828                                                         VectorScale(pDif, 12.0f/difLen, pDif);
03829                                                         difLen = 12.0f;
03830                                                 }
03831 
03832                                                 while (cg_effectorStringTable[i])
03833                                                 {
03834