codemp/game/g_client.c File Reference

#include "g_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 JMSABER_RESPAWN_TIME   20000
#define MAX_SPAWN_POINTS   128
#define MAX_SPAWN_POINTS   128
#define BODY_SINK_TIME   30000

Functions

void WP_SaberAddG2Model (gentity_t *saberent, const char *saberModel, qhandle_t saberSkin)
void WP_SaberRemoveG2Model (gentity_t *saberent)
qboolean WP_SaberStyleValidForSaber (saberInfo_t *saber1, saberInfo_t *saber2, int saberHolstered, int saberAnimLevel)
qboolean WP_UseFirstValidSaberStyle (saberInfo_t *saber1, saberInfo_t *saber2, int saberHolstered, int *saberAnimLevel)
void SP_info_player_duel (gentity_t *ent)
void SP_info_player_duel1 (gentity_t *ent)
void SP_info_player_duel2 (gentity_t *ent)
void SP_info_player_deathmatch (gentity_t *ent)
void SP_info_player_start (gentity_t *ent)
void SP_info_player_start_red (gentity_t *ent)
void SP_info_player_start_blue (gentity_t *ent)
void SiegePointUse (gentity_t *self, gentity_t *other, gentity_t *activator)
void SP_info_player_siegeteam1 (gentity_t *ent)
void SP_info_player_siegeteam2 (gentity_t *ent)
void SP_info_player_intermission (gentity_t *ent)
void SP_info_player_intermission_red (gentity_t *ent)
void SP_info_player_intermission_blue (gentity_t *ent)
void ThrowSaberToAttacker (gentity_t *self, gentity_t *attacker)
void JMSaberThink (gentity_t *ent)
void JMSaberTouch (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_info_jedimaster_start (gentity_t *ent)
qboolean SpotWouldTelefrag (gentity_t *spot)
qboolean SpotWouldTelefrag2 (gentity_t *mover, vec3_t dest)
gentity_tSelectNearestDeathmatchSpawnPoint (vec3_t from)
gentity_tSelectRandomDeathmatchSpawnPoint (void)
gentity_tSelectRandomFurthestSpawnPoint (vec3_t avoidPoint, vec3_t origin, vec3_t angles, team_t team)
gentity_tSelectDuelSpawnPoint (int team, vec3_t avoidPoint, vec3_t origin, vec3_t angles)
gentity_tSelectSpawnPoint (vec3_t avoidPoint, vec3_t origin, vec3_t angles, team_t team)
gentity_tSelectInitialSpawnPoint (vec3_t origin, vec3_t angles, team_t team)
gentity_tSelectSpectatorSpawnPoint (vec3_t origin, vec3_t angles)
void InitBodyQue (void)
void BodySink (gentity_t *ent)
void SetClientViewAngle (gentity_t *ent, vec3_t angle)
void MaintainBodyQueue (gentity_t *ent)
void SiegeRespawn (gentity_t *ent)
void respawn (gentity_t *ent)
team_t TeamCount (int ignoreClientNum, int team)
int TeamLeader (int team)
team_t PickTeam (int ignoreClientNum)
qboolean G_SaberModelSetup (gentity_t *ent)
qboolean BG_IsValidCharacterModel (const char *modelName, const char *skinName)
qboolean BG_ValidateSkinForTeam (const char *modelName, char *skinName, int team, float *colors)
void BG_GetVehicleModelName (char *modelname)
void SetupGameGhoul2Model (gentity_t *ent, char *modelname, char *skinName)
qboolean G_SetSaber (gentity_t *ent, int saberNum, char *saberName, qboolean siegeOverride)
void G_ValidateSiegeClassForTeam (gentity_t *ent, int team)
void ClientUserinfoChanged (int clientNum)
char * ClientConnect (int clientNum, qboolean firstTime, qboolean isBot)
void G_WriteClientSessionData (gclient_t *client)
void WP_SetSaber (int entNum, saberInfo_t *sabers, int saberNum, const char *saberName)
void SetTeamQuick (gentity_t *ent, int team, qboolean doBegin)
void ClientBegin (int clientNum, qboolean allowTeamReset)
void G_BreakArm (gentity_t *ent, int arm)
qboolean BG_SaberStanceAnim (int anim)
qboolean PM_RunningAnim (int anim)
void G_UpdateClientAnims (gentity_t *self, float animSpeedScale)
qboolean WP_HasForcePowers (const playerState_t *ps)
void ClientSpawn (gentity_t *ent)
void ClientDisconnect (int clientNum)

Variables

int g_siegeRespawnCheck
forcedata_t Client_Force [MAX_CLIENTS]
gentity_tgJMSaberEnt = NULL
void * g2SaberInstance = NULL
qboolean gSiegeRoundBegun
qboolean gSiegeRoundEnded


Define Documentation

#define BODY_SINK_TIME   30000
 

Definition at line 946 of file g_client.c.

Referenced by BodySink().

#define JMSABER_RESPAWN_TIME   20000
 

Definition at line 256 of file g_client.c.

Referenced by JMSaberThink(), and JMSaberTouch().

#define MAX_SPAWN_POINTS   128
 

Definition at line 621 of file g_client.c.

#define MAX_SPAWN_POINTS   128
 

Definition at line 621 of file g_client.c.

Referenced by SelectRandomDeathmatchSpawnPoint().


Function Documentation

void BG_GetVehicleModelName char *  modelname  ) 
 

Definition at line 1599 of file bg_vehicleLoad.c.

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

Referenced by CG_CacheG2AnimInfo(), CG_G2AnimEntModelLoad(), and SetupGameGhoul2Model().

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 }

qboolean BG_IsValidCharacterModel const char *  modelName,
const char *  skinName
 

Definition at line 2744 of file bg_misc.c.

References Q_stricmp(), qboolean, qfalse, and qtrue.

Referenced by BG_ValidateSkinForTeam(), and SetupGameGhoul2Model().

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.

References BOTH_SABERDUAL_STANCE, BOTH_SABERFAST_STANCE, BOTH_SABERSLOW_STANCE, BOTH_SABERSTAFF_STANCE, BOTH_STAND1, BOTH_STAND2, qboolean, qfalse, and qtrue.

Referenced by G_UpdateClientAnims().

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_ValidateSkinForTeam const char *  modelName,
char *  skinName,
int  team,
float *  colors
 

Definition at line 2768 of file bg_misc.c.

References BG_FileExists(), BG_IsValidCharacterModel(), MAX_QPATH, Q_strcat(), Q_stricmp(), Q_stricmpn(), Q_strncmp(), Q_strncpyz(), qboolean, qfalse, qtrue, strchr(), strlen(), TEAM_BLUE, TEAM_RED, and va().

Referenced by CG_NewClientInfo(), and SetupGameGhoul2Model().

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 BodySink gentity_t ent  ) 
 

Definition at line 973 of file g_client.c.

References BODY_SINK_TIME, EV_BODYFADE, G_AddEvent(), gentity_t, level, gentity_s::nextthink, gentity_s::physicsObject, qfalse, gentity_s::takedamage, level_locals_t::time, gentity_s::timestamp, and trap_UnlinkEntity().

00973                                 {
00974         if ( level.time - ent->timestamp > BODY_SINK_TIME + 2500 ) {
00975                 // the body ques are never actually freed, they are just unlinked
00976                 trap_UnlinkEntity( ent );
00977                 ent->physicsObject = qfalse;
00978                 return; 
00979         }
00980 //      ent->nextthink = level.time + 100;
00981 //      ent->s.pos.trBase[2] -= 1;
00982 
00983         G_AddEvent(ent, EV_BODYFADE, 0);
00984         ent->nextthink = level.time + 18000;
00985         ent->takedamage = qfalse;
00986 }

void ClientBegin int  clientNum,
qboolean  allowTeamReset
 

Definition at line 2385 of file g_client.c.

References CalculateRanks(), CHAN_VOICE, client, gentity_s::client, entityState_s::clientNum, level_locals_t::clients, ClientSpawn(), ClientUserinfoChanged(), CON_CONNECTED, clientPersistant_t::connected, clientSession_t::duelTeam, DUELTEAM_FREE, playerState_s::eFlags, clientPersistant_t::enterTime, EV_PLAYER_TELEPORT_IN, playerState_s::fd, forcedata_s::forcePowersActive, G_ClearClientLog(), g_entities, g_gametype, G_GetStringEdString(), G_InitGentity(), G_LogPrintf(), G_MuteSound(), G_ReadSessionData(), G_SetSaber(), G_TempEntity(), G_WriteClientSessionData(), gclient_t, gentity_t, gentity_s::ghoul2, gSiegeRoundBegun, gSiegeRoundEnded, GT_DUEL, GT_POWERDUEL, GT_SIEGE, GT_TEAM, playerState_s::hasDetPackPlanted, Info_SetValueForKey(), Info_ValueForKey(), vmCvar_t::integer, forcedata_s::killSoundEntIndex, renderInfo_s::lastG2, level, entityShared_t::linked, MAX_GENTITIES, MAX_INFO_STRING, MAX_INFO_VALUE, memset(), clientPersistant_t::netname, NULL, NUM_FORCE_POWERS, NUM_TRACK_CHANNELS, playerState_s::origin, gentity_s::pain, gclient_s::pers, PERS_TEAM, playerState_s::persistant, PickTeam(), gentity_s::playerState, gclient_s::ps, qfalse, gentity_s::r, rand(), gclient_s::renderInfo, gentity_s::s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, SetTeam(), SetTeamQuick(), SetupGameGhoul2Model(), playerTeamState_t::state, strcpy(), SVF_BOT, entityShared_t::svFlags, TEAM_BEGIN, TEAM_RED, TEAM_SPECTATOR, clientPersistant_t::teamState, level_locals_t::time, gentity_s::touch, TRACK_CHANNEL_1, trap_GetUserinfo(), trap_SendServerCommand(), trap_SetUserinfo(), trap_UnlinkEntity(), va(), WP_ForcePowerStop(), WP_InitForcePowers(), and WP_SaberInitBladeData().

Referenced by Cmd_SiegeClass_f(), G_CheckBotSpawn(), SetTeam(), SetTeamQuick(), SpectatorClientEndFrame(), and vmMain().

02385                                                            {
02386         gentity_t       *ent;
02387         gclient_t       *client;
02388         gentity_t       *tent;
02389         int                     flags, i;
02390         char            userinfo[MAX_INFO_VALUE], *modelname;
02391 
02392         ent = g_entities + clientNum;
02393 
02394         if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM)
02395         {
02396                 if (allowTeamReset)
02397                 {
02398                         const char *team = "Red";
02399                         int preSess;
02400 
02401                         //SetTeam(ent, "");
02402                         ent->client->sess.sessionTeam = PickTeam(-1);
02403                         trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);
02404 
02405                         if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
02406                         {
02407                                 ent->client->sess.sessionTeam = TEAM_RED;
02408                         }
02409 
02410                         if (ent->client->sess.sessionTeam == TEAM_RED)
02411                         {
02412                                 team = "Red";
02413                         }
02414                         else
02415                         {
02416                                 team = "Blue";
02417                         }
02418 
02419                         Info_SetValueForKey( userinfo, "team", team );
02420 
02421                         trap_SetUserinfo( clientNum, userinfo );
02422 
02423                         ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam;
02424 
02425                         preSess = ent->client->sess.sessionTeam;
02426                         G_ReadSessionData( ent->client );
02427                         ent->client->sess.sessionTeam = preSess;
02428                         G_WriteClientSessionData(ent->client);
02429                         ClientUserinfoChanged( clientNum );
02430                         ClientBegin(clientNum, qfalse);
02431                         return;
02432                 }
02433         }
02434 
02435         client = level.clients + clientNum;
02436 
02437         if ( ent->r.linked ) {
02438                 trap_UnlinkEntity( ent );
02439         }
02440         G_InitGentity( ent );
02441         ent->touch = 0;
02442         ent->pain = 0;
02443         ent->client = client;
02444 
02445         //assign the pointer for bg entity access
02446         ent->playerState = &ent->client->ps;
02447 
02448         client->pers.connected = CON_CONNECTED;
02449         client->pers.enterTime = level.time;
02450         client->pers.teamState.state = TEAM_BEGIN;
02451 
02452         // save eflags around this, because changing teams will
02453         // cause this to happen with a valid entity, and we
02454         // want to make sure the teleport bit is set right
02455         // so the viewpoint doesn't interpolate through the
02456         // world to the new position
02457         flags = client->ps.eFlags;
02458 
02459         i = 0;
02460 
02461         while (i < NUM_FORCE_POWERS)
02462         {
02463                 if (ent->client->ps.fd.forcePowersActive & (1 << i))
02464                 {
02465                         WP_ForcePowerStop(ent, i);
02466                 }
02467                 i++;
02468         }
02469 
02470         i = TRACK_CHANNEL_1;
02471 
02472         while (i < NUM_TRACK_CHANNELS)
02473         {
02474                 if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0)
02475                 {
02476                         G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE);
02477                 }
02478                 i++;
02479         }
02480         i = 0;
02481 
02482         memset( &client->ps, 0, sizeof( client->ps ) );
02483         client->ps.eFlags = flags;
02484 
02485         client->ps.hasDetPackPlanted = qfalse;
02486 
02487         //first-time force power initialization
02488         WP_InitForcePowers( ent );
02489 
02490         //init saber ent
02491         WP_SaberInitBladeData( ent );
02492 
02493         // First time model setup for that player.
02494         trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
02495         modelname = Info_ValueForKey (userinfo, "model");
02496         SetupGameGhoul2Model(ent, modelname, NULL);
02497 
02498         if (ent->ghoul2 && ent->client)
02499         {
02500                 ent->client->renderInfo.lastG2 = NULL; //update the renderinfo bolts next update.
02501         }
02502 
02503         if (g_gametype.integer == GT_POWERDUEL && client->sess.sessionTeam != TEAM_SPECTATOR &&
02504                 client->sess.duelTeam == DUELTEAM_FREE)
02505         {
02506                 SetTeam(ent, "s");
02507         }
02508         else
02509         {
02510                 if (g_gametype.integer == GT_SIEGE && (!gSiegeRoundBegun || gSiegeRoundEnded))
02511                 {
02512                         SetTeamQuick(ent, TEAM_SPECTATOR, qfalse);
02513                 }
02514         
02515                 if ((ent->r.svFlags & SVF_BOT) &&
02516                         g_gametype.integer != GT_SIEGE)
02517                 {
02518                         char *saberVal = Info_ValueForKey(userinfo, "saber1");
02519                         char *saber2Val = Info_ValueForKey(userinfo, "saber2");
02520 
02521                         if (!saberVal || !saberVal[0])
02522                         { //blah, set em up with a random saber
02523                                 int r = rand()%50;
02524                                 char sab1[1024];
02525                                 char sab2[1024];
02526 
02527                                 if (r <= 17)
02528                                 {
02529                                         strcpy(sab1, "Katarn");
02530                                         strcpy(sab2, "none");
02531                                 }
02532                                 else if (r <= 34)
02533                                 {
02534                                         strcpy(sab1, "Katarn");
02535                                         strcpy(sab2, "Katarn");
02536                                 }
02537                                 else
02538                                 {
02539                                         strcpy(sab1, "dual_1");
02540                                         strcpy(sab2, "none");
02541                                 }
02542                                 G_SetSaber(ent, 0, sab1, qfalse);
02543                                 G_SetSaber(ent, 0, sab2, qfalse);
02544                                 Info_SetValueForKey( userinfo, "saber1", sab1 );
02545                                 Info_SetValueForKey( userinfo, "saber2", sab2 );
02546                                 trap_SetUserinfo( clientNum, userinfo );
02547                         }
02548                         else
02549                         {
02550                                 G_SetSaber(ent, 0, saberVal, qfalse);
02551                         }
02552 
02553                         if (saberVal && saberVal[0] &&
02554                                 (!saber2Val || !saber2Val[0]))
02555                         {
02556                                 G_SetSaber(ent, 0, "none", qfalse);
02557                                 Info_SetValueForKey( userinfo, "saber2", "none" );
02558                                 trap_SetUserinfo( clientNum, userinfo );
02559                         }
02560                         else
02561                         {
02562                                 G_SetSaber(ent, 0, saber2Val, qfalse);
02563                         }
02564                 }
02565 
02566                 // locate ent at a spawn point
02567                 ClientSpawn( ent );
02568         }
02569 
02570         if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
02571                 // send event
02572                 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
02573                 tent->s.clientNum = ent->s.clientNum;
02574 
02575                 if ( g_gametype.integer != GT_DUEL || g_gametype.integer == GT_POWERDUEL ) {
02576                         trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStringEdString("MP_SVGAME", "PLENTER")) );
02577                 }
02578         }
02579         G_LogPrintf( "ClientBegin: %i\n", clientNum );
02580 
02581         // count current clients and rank for scoreboard
02582         CalculateRanks();
02583 
02584         G_ClearClientLog(clientNum);
02585 }

char* ClientConnect int  clientNum,
qboolean  firstTime,
qboolean  isBot
 

Definition at line 2258 of file g_client.c.

References BroadcastTeamChange(), CalculateRanks(), client, gentity_s::client, level_locals_t::clients, ClientUserinfoChanged(), CON_CONNECTING, clientPersistant_t::connected, EV_CLIENTJOIN, entityState_s::eventParm, G_BotConnect(), g_entities, G_FilterPacket(), g_gametype, G_GetStringEdString(), G_InitSessionData(), G_LogPrintf(), g_needpass, g_password, G_ReadSessionData(), G_TempEntity(), gclient_t, gentity_t, GT_POWERDUEL, GT_SIEGE, GT_TEAM, Info_ValueForKey(), vmCvar_t::integer, gentity_s::inuse, level, MAX_INFO_STRING, memset(), clientPersistant_t::netname, level_locals_t::newSession, NULL, gclient_s::pers, gentity_s::playerState, gclient_s::ps, Q_stricmp(), Q_strncpyz(), qtrue, gentity_s::r, gentity_s::s, S_COLOR_WHITE, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::siegeDesiredTeam, strcmp(), vmCvar_t::string, SVF_BOT, SVF_BROADCAST, entityShared_t::svFlags, TEAM_SPECTATOR, trap_GetUserinfo(), trap_SendServerCommand(), va(), and vec3_origin.

Referenced by vmMain().

02258                                                                          {
02259         char            *value;
02260 //      char            *areabits;
02261         gclient_t       *client;
02262         char            userinfo[MAX_INFO_STRING];
02263         gentity_t       *ent;
02264         gentity_t       *te;
02265 
02266         ent = &g_entities[ clientNum ];
02267 
02268         trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
02269 
02270         // check to see if they are on the banned IP list
02271         value = Info_ValueForKey (userinfo, "ip");
02272         if ( G_FilterPacket( value ) ) {
02273                 return "Banned.";
02274         }
02275 
02276         if ( !( ent->r.svFlags & SVF_BOT ) && !isBot && g_needpass.integer ) {
02277                 // check for a password
02278                 value = Info_ValueForKey (userinfo, "password");
02279                 if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) &&
02280                         strcmp( g_password.string, value) != 0) {
02281                         static char sTemp[1024];
02282                         Q_strncpyz(sTemp, G_GetStringEdString("MP_SVGAME","INVALID_ESCAPE_TO_MAIN"), sizeof (sTemp) );
02283                         return sTemp;// return "Invalid password";
02284                 }
02285         }
02286 
02287         // they can connect
02288         ent->client = level.clients + clientNum;
02289         client = ent->client;
02290 
02291         //assign the pointer for bg entity access
02292         ent->playerState = &ent->client->ps;
02293 
02294 //      areabits = client->areabits;
02295 
02296         memset( client, 0, sizeof(*client) );
02297 
02298         client->pers.connected = CON_CONNECTING;
02299 
02300         // read or initialize the session data
02301         if ( firstTime || level.newSession ) {
02302                 G_InitSessionData( client, userinfo, isBot );
02303         }
02304         G_ReadSessionData( client );
02305 
02306         if (g_gametype.integer == GT_SIEGE &&
02307                 (firstTime || level.newSession))
02308         { //if this is the first time then auto-assign a desired siege team and show briefing for that team
02309                 client->sess.siegeDesiredTeam = 0;//PickTeam(ent->s.number);
02310                 /*
02311                 trap_SendServerCommand(ent->s.number, va("sb %i", client->sess.siegeDesiredTeam));
02312                 */
02313                 //don't just show it - they'll see it if they switch to a team on purpose.
02314         }
02315 
02316 
02317         if (g_gametype.integer == GT_SIEGE && client->sess.sessionTeam != TEAM_SPECTATOR)
02318         {
02319                 if (firstTime || level.newSession)
02320                 { //start as spec
02321                         client->sess.siegeDesiredTeam = client->sess.sessionTeam;
02322                         client->sess.sessionTeam = TEAM_SPECTATOR;
02323                 }
02324         }
02325         else if (g_gametype.integer == GT_POWERDUEL && client->sess.sessionTeam != TEAM_SPECTATOR)
02326         {
02327                 client->sess.sessionTeam = TEAM_SPECTATOR;
02328         }
02329 
02330         if( isBot ) {
02331                 ent->r.svFlags |= SVF_BOT;
02332                 ent->inuse = qtrue;
02333                 if( !G_BotConnect( clientNum, !firstTime ) ) {
02334                         return "BotConnectfailed";
02335                 }
02336         }
02337 
02338         // get and distribute relevent paramters
02339         G_LogPrintf( "ClientConnect: %i\n", clientNum );
02340         ClientUserinfoChanged( clientNum );
02341 
02342         // don't do the "xxx connected" messages if they were caried over from previous level
02343         if ( firstTime ) {
02344                 trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStringEdString("MP_SVGAME", "PLCONNECT")) );
02345         }
02346 
02347         if ( g_gametype.integer >= GT_TEAM &&
02348                 client->sess.sessionTeam != TEAM_SPECTATOR ) {
02349                 BroadcastTeamChange( client, -1 );
02350         }
02351 
02352         // count current clients and rank for scoreboard
02353         CalculateRanks();
02354 
02355         te = G_TempEntity( vec3_origin, EV_CLIENTJOIN );
02356         te->r.svFlags |= SVF_BROADCAST;
02357         te->s.eventParm = clientNum;
02358 
02359         // for statistics
02360 //      client->areabits = areabits;
02361 //      if ( !client->areabits )
02362 //              client->areabits = G_Alloc( (trap_AAS_PointReachabilityAreaIndex( NULL ) + 7) / 8 );
02363 
02364         return NULL;
02365 }

void ClientDisconnect int  clientNum  ) 
 

Definition at line 3808 of file g_client.c.

References bgEntity_t, BotAIShutdownClient(), CalculateRanks(), CHAN_VOICE, gentity_s::classname, gentity_s::client, entityState_s::clientNum, level_locals_t::clients, ClientUserinfoChanged(), CON_CONNECTED, CON_DISCONNECTED, clientPersistant_t::connected, entityShared_t::contents, CS_PLAYERS, vehicleInfo_t::Eject, EV_PLAYER_TELEPORT_OUT, playerState_s::fd, forcedata_s::forcePowersActive, G_ClearClientLog(), g_entities, g_gametype, G_LogPrintf(), G_MuteSound(), G_RemoveQueuedBotBegin(), G_TempEntity(), gentity_t, gentity_s::ghoul2, GT_DUEL, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, forcedata_s::killSoundEntIndex, level, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_GENTITIES, MAX_SABERS, level_locals_t::maxclients, entityState_s::modelindex, NUM_FORCE_POWERS, NUM_TRACK_CHANNELS, playerState_s::origin, gclient_s::pers, PERS_SCORE, PERS_TEAM, playerState_s::persistant, gclient_s::ps, qfalse, qtrue, gentity_s::r, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, level_locals_t::sortedClients, SPECTATOR_FOLLOW, clientSession_t::spectatorClient, clientSession_t::spectatorState, StopFollowing(), SVF_BOT, entityShared_t::svFlags, TEAM_FREE, TEAM_SPECTATOR, TossClientItems(), TRACK_CHANNEL_1, trap_G2_HaveWeGhoul2Models(), trap_G2API_CleanGhoul2Models(), trap_SetConfigstring(), trap_UnlinkEntity(), level_locals_t::warmupTime, gclient_s::weaponGhoul2, and WP_ForcePowerStop().

Referenced by vmMain().

03808                                        {
03809         gentity_t       *ent;
03810         gentity_t       *tent;
03811         int                     i;
03812 
03813         // cleanup if we are kicking a bot that
03814         // hasn't spawned yet
03815         G_RemoveQueuedBotBegin( clientNum );
03816 
03817         ent = g_entities + clientNum;
03818         if ( !ent->client ) {
03819                 return;
03820         }
03821 
03822         i = 0;
03823 
03824         while (i < NUM_FORCE_POWERS)
03825         {
03826                 if (ent->client->ps.fd.forcePowersActive & (1 << i))
03827                 {
03828                         WP_ForcePowerStop(ent, i);
03829                 }
03830                 i++;
03831         }
03832 
03833         i = TRACK_CHANNEL_1;
03834 
03835         while (i < NUM_TRACK_CHANNELS)
03836         {
03837                 if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0)
03838                 {
03839                         G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE);
03840                 }
03841                 i++;
03842         }
03843         i = 0;
03844 
03845         if (ent->client->ps.m_iVehicleNum)
03846         { //tell it I'm getting off
03847                 gentity_t *veh = &g_entities[ent->client->ps.m_iVehicleNum];
03848 
03849                 if (veh->inuse && veh->client && veh->m_pVehicle)
03850                 {
03851                         int pCon = ent->client->pers.connected;
03852 
03853                         ent->client->pers.connected = 0;
03854                         veh->m_pVehicle->m_pVehicleInfo->Eject(veh->m_pVehicle, (bgEntity_t *)ent, qtrue);
03855                         ent->client->pers.connected = pCon;
03856                 }
03857         }
03858 
03859         // stop any following clients
03860         for ( i = 0 ; i < level.maxclients ; i++ ) {
03861                 if ( level.clients[i].sess.sessionTeam == TEAM_SPECTATOR
03862                         && level.clients[i].sess.spectatorState == SPECTATOR_FOLLOW
03863                         && level.clients[i].sess.spectatorClient == clientNum ) {
03864                         StopFollowing( &g_entities[i] );
03865                 }
03866         }
03867 
03868         // send effect if they were completely connected
03869         if ( ent->client->pers.connected == CON_CONNECTED 
03870                 && ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
03871                 tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT );
03872                 tent->s.clientNum = ent->s.clientNum;
03873 
03874                 // They don't get to take powerups with them!
03875                 // Especially important for stuff like CTF flags
03876                 TossClientItems( ent );
03877         }
03878 
03879         G_LogPrintf( "ClientDisconnect: %i\n", clientNum );
03880 
03881         // if we are playing in tourney mode, give a win to the other player and clear his frags for this round
03882         if ( (g_gametype.integer == GT_DUEL )
03883                 && !level.intermissiontime
03884                 && !level.warmupTime ) {
03885                 if ( level.sortedClients[1] == clientNum ) {
03886                         level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE] = 0;
03887                         level.clients[ level.sortedClients[0] ].sess.wins++;
03888                         ClientUserinfoChanged( level.sortedClients[0] );
03889                 }
03890                 else if ( level.sortedClients[0] == clientNum ) {
03891                         level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE] = 0;
03892                         level.clients[ level.sortedClients[1] ].sess.wins++;
03893                         ClientUserinfoChanged( level.sortedClients[1] );
03894                 }
03895         }
03896 
03897         if (ent->ghoul2 && trap_G2_HaveWeGhoul2Models(ent->ghoul2))
03898         {
03899                 trap_G2API_CleanGhoul2Models(&ent->ghoul2);
03900         }
03901         i = 0;
03902         while (i < MAX_SABERS)
03903         {
03904                 if (ent->client->weaponGhoul2[i] && trap_G2_HaveWeGhoul2Models(ent->client->weaponGhoul2[i]))
03905                 {
03906                         trap_G2API_CleanGhoul2Models(&ent->client->weaponGhoul2[i]);
03907                 }
03908                 i++;
03909         }
03910 
03911         trap_UnlinkEntity (ent);
03912         ent->s.modelindex = 0;
03913         ent->inuse = qfalse;
03914         ent->classname = "disconnected";
03915         ent->client->pers.connected = CON_DISCONNECTED;
03916         ent->client->ps.persistant[PERS_TEAM] = TEAM_FREE;
03917         ent->client->sess.sessionTeam = TEAM_FREE;
03918         ent->r.contents = 0;
03919 
03920         trap_SetConfigstring( CS_PLAYERS + clientNum, "");
03921 
03922         CalculateRanks();
03923 
03924         if ( ent->r.svFlags & SVF_BOT ) {
03925                 BotAIShutdownClient( clientNum, qfalse );
03926         }
03927 
03928         G_ClearClientLog(clientNum);
03929 }

void ClientSpawn gentity_t ent  ) 
 

Definition at line 2930 of file g_client.c.

References gclient_s::accuracy_hits, gclient_s::accuracy_shots, gclient_s::airOutTime, playerState_s::ammo, AMMO_BLASTER, AMMO_POWERCELL, ammoData, weaponData_s::ammoIndex, atoi(), BG_PlayerStateToEntityState(), bgSiegeClasses, gclient_s::bodyGrabIndex, BOTH_STAND1TO2, CFL_EXTRA_AMMO, CFL_SINGLE_ROCKET, gentity_s::classname, client, gentity_s::client, ClientEndFrame(), playerState_s::clientNum, level_locals_t::clients, ClientThink(), ClientUserinfoChanged(), gentity_s::clipmask, playerState_s::cloakFuel, clientPersistant_t::cmd, playerState_s::commandTime, CON_DISCONNECTED, clientPersistant_t::connected, entityShared_t::contents, CONTENTS_BODY, CROUCH_MAXS_2, playerState_s::crouchheight, entityShared_t::currentOrigin, playerState_s::customRGBA, DEFAULT_MAXS_2, gentity_s::die, playerState_s::duelIndex, clientSession_t::duelTeam, DUELTEAM_LONE, DUELTEAM_SINGLE, EF_DOUBLE_AMMO, EF_INVULNERABLE, EF_TELEPORT_BIT, playerState_s::eFlags, gclient_s::enemyTeam, ENTITYNUM_NONE, playerState_s::eventSequence, playerState_s::fallingToDeath, playerState_s::fd, FL_NO_BOTS, FL_NO_HUMANS, gentity_s::flags, forcedata_t, forcedata_s::forceDoInit, forcedata_s::forcePowerLevel, FP_SABER_OFFENSE, g_duel_fraglimit, g_duelWeaponDisable, g_entities, g_forcePowerDisable, g_gametype, g_inactivity, G_KillBox(), g_powerDuelEndHealth, g_powerDuelStartHealth, G_SaberModelSetup(), G_SetAnim(), G_SetOrigin(), G_SetSaber(), g_spawnInvulnerability, g_trueJedi, G_UseTargets(), g_weaponDisable, gclient_t, playerState_s::genericEnemyIndex, gentity_t, entityState_s::groundEntityNum, GT_CTF, GT_CTY, GT_DUEL, GT_HOLOCRON, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, GT_TEAM, HasSetSaberOnly(), gentity_s::health, HL_MAX, gclient_s::inactivityTime, Info_SetValueForKey(), Info_ValueForKey(), clientPersistant_t::initialSpawn, vmCvar_t::integer, level_locals_t::intermissiontime, gentity_s::inuse, gclient_s::invulnerableTimer, playerState_s::isJediMaster, playerState_s::jetpackFuel, gclient_s::lastkilled_client, gclient_s::latched_buttons, playerState_s::legsAnim, playerState_s::legsTimer, level, clientPersistant_t::localClient, gentity_s::locationDamage, MASK_PLAYERSOLID, MAX_INFO_STRING, MAX_PERSISTANT, MAX_SABERS, level_locals_t::maxclients, siegeClass_t::maxhealth, clientPersistant_t::maxHealth,