diff options
Diffstat (limited to 'src/game/g_client.c')
-rw-r--r-- | src/game/g_client.c | 155 |
1 files changed, 75 insertions, 80 deletions
diff --git a/src/game/g_client.c b/src/game/g_client.c index d137b9bb..d8fb60a9 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -13,7 +13,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ - + #include "g_local.h" // g_client.c -- client functions that don't happen every frame @@ -33,7 +33,7 @@ void SP_info_player_deathmatch( gentity_t *ent ) int i; G_SpawnInt( "nobots", "0", &i); - + if( i ) ent->flags |= FL_NO_BOTS; @@ -98,9 +98,9 @@ void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ) return; } } - + client->ps.persistant[ PERS_CREDIT ] += credit; - + if( cap ) { if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) @@ -114,7 +114,7 @@ void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ) client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; } } - + if( client->ps.persistant[ PERS_CREDIT ] < 0 ) client->ps.persistant[ PERS_CREDIT ] = 0; } @@ -179,7 +179,7 @@ gentity_t *SelectNearestDeathmatchSpawnPoint( vec3_t from ) { VectorSubtract( spot->s.origin, from, delta ); dist = VectorLength( delta ); - + if( dist < nearestDist ) { nearestDist = dist; @@ -252,31 +252,31 @@ gentity_t *SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, ve VectorSubtract( spot->s.origin, avoidPoint, delta ); dist = VectorLength( delta ); - + for( i = 0; i < numSpots; i++ ) { if( dist > list_dist[ i ] ) { if( numSpots >= 64 ) numSpots = 64 - 1; - + for( j = numSpots; j > i; j-- ) { list_dist[ j ] = list_dist[ j - 1 ]; list_spot[ j ] = list_spot[ j - 1 ]; } - + list_dist[ i ] = dist; list_spot[ i ] = spot; numSpots++; - + if( numSpots > 64 ) numSpots = 64; - + break; } } - + if( i >= numSpots && numSpots < 64 ) { list_dist[ numSpots ] = dist; @@ -284,14 +284,14 @@ gentity_t *SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, ve numSpots++; } } - + if( !numSpots ) { spot = G_Find( NULL, FOFS( classname ), "info_player_deathmatch" ); - + if( !spot ) G_Error( "Couldn't find a spawn point" ); - + VectorCopy( spot->s.origin, origin ); origin[ 2 ] += 9; VectorCopy( spot->s.angles, angles ); @@ -324,7 +324,7 @@ gentity_t *SelectAlienSpawnPoint( vec3_t preference ) if( level.numAlienSpawns <= 0 ) return NULL; - + count = 0; spot = NULL; @@ -333,7 +333,7 @@ gentity_t *SelectAlienSpawnPoint( vec3_t preference ) { if( !spot->spawned ) continue; - + if( spot->health <= 0 ) continue; @@ -342,10 +342,11 @@ gentity_t *SelectAlienSpawnPoint( vec3_t preference ) if( spot->clientSpawnTime > 0 ) continue; - - if( G_CheckSpawnPoint( spot->s.origin, spot->s.origin2, BA_A_SPAWN, NULL ) != NULL ) + + if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, + spot->s.origin2, BA_A_SPAWN, NULL ) != NULL ) continue; - + spots[ count ] = spot; count++; } @@ -372,7 +373,7 @@ gentity_t *SelectHumanSpawnPoint( vec3_t preference ) if( level.numHumanSpawns <= 0 ) return NULL; - + count = 0; spot = NULL; @@ -381,7 +382,7 @@ gentity_t *SelectHumanSpawnPoint( vec3_t preference ) { if( !spot->spawned ) continue; - + if( spot->health <= 0 ) continue; @@ -390,10 +391,11 @@ gentity_t *SelectHumanSpawnPoint( vec3_t preference ) if( spot->clientSpawnTime > 0 ) continue; - - if( G_CheckSpawnPoint( spot->s.origin, spot->s.origin2, BA_H_SPAWN, NULL ) != NULL ) + + if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, + spot->s.origin2, BA_H_SPAWN, NULL ) != NULL ) continue; - + spots[ count ] = spot; count++; } @@ -439,15 +441,15 @@ gentity_t *SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t or return NULL; if( team == PTE_ALIENS ) - G_CheckSpawnPoint( spot->s.origin, spot->s.origin2, BA_A_SPAWN, origin ); + G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_A_SPAWN, origin ); else if( team == PTE_HUMANS ) - G_CheckSpawnPoint( spot->s.origin, spot->s.origin2, BA_H_SPAWN, origin ); + G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_H_SPAWN, origin ); VectorCopy( spot->s.angles, angles ); angles[ ROLL ] = 0; return spot; - + } @@ -571,18 +573,18 @@ void BodySink( gentity_t *ent ) if( !ent->active ) { ent->active = qtrue; - + //sinking bodies can't be infested ent->killedBy = ent->s.powerups = MAX_CLIENTS; ent->timestamp = level.time; } - + if( level.time - ent->timestamp > 6500 ) { G_FreeEntity( ent ); return; } - + ent->nextthink = level.time + 100; ent->s.pos.trBase[ 2 ] -= 1; } @@ -629,7 +631,7 @@ void SpawnCorpse( gentity_t *ent ) contents = trap_PointContents( origin, -1 ); if( contents & CONTENTS_NODROP ) return; - + body = G_Spawn( ); VectorCopy( ent->s.apos.trBase, body->s.angles ); @@ -639,10 +641,9 @@ void SpawnCorpse( gentity_t *ent ) body->timestamp = level.time; body->s.event = 0; body->r.contents = CONTENTS_CORPSE; - body->clipmask = MASK_DEADSOLID; body->s.clientNum = ent->client->ps.stats[ STAT_PCLASS ]; body->nonSegModel = ent->client->ps.persistant[ PERS_STATE ] & PS_NONSEGMODEL; - + if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) body->classname = "humanCorpse"; else @@ -651,8 +652,8 @@ void SpawnCorpse( gentity_t *ent ) body->s.powerups = MAX_CLIENTS; body->think = BodySink; - body->nextthink = level.time + 60000; - + body->nextthink = level.time + 20000; + body->s.legsAnim = ent->s.legsAnim; if( !body->nonSegModel ) @@ -698,11 +699,11 @@ void SpawnCorpse( gentity_t *ent ) body->health = ent->health = ent->client->ps.stats[ STAT_HEALTH ]; ent->health = 0; - + //change body dimensions BG_FindBBoxForClass( ent->client->ps.stats[ STAT_PCLASS ], NULL, NULL, NULL, body->r.mins, body->r.maxs ); vDiff = body->r.mins[ 2 ] - ent->r.mins[ 2 ]; - + //drop down to match the *model* origins of ent and body VectorSet( dest, origin[ 0 ], origin[ 1 ], origin[ 2 ] - vDiff ); trap_Trace( &tr, origin, body->r.mins, body->r.maxs, dest, body->s.number, body->clipmask ); @@ -713,7 +714,7 @@ void SpawnCorpse( gentity_t *ent ) body->s.pos.trType = TR_GRAVITY; body->s.pos.trTime = level.time; VectorCopy( ent->client->ps.velocity, body->s.pos.trDelta ); - + VectorCopy ( body->s.pos.trBase, body->r.currentOrigin ); trap_LinkEntity( body ); } @@ -739,7 +740,7 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) cmdAngle = ANGLE2SHORT( angle[ i ] ); ent->client->ps.delta_angles[ i ] = cmdAngle - ent->client->pers.cmd.angles[ i ]; } - + VectorCopy( angle, ent->s.angles ); VectorCopy( ent->s.angles, ent->client->ps.viewangles ); } @@ -755,12 +756,6 @@ void respawn( gentity_t *ent ) //TA: Clients can't respawn - they must go thru the class cmd ClientSpawn( ent, NULL, NULL, NULL ); - - //FIXME: need different spawn effects for different teams - - // add a teleportation effect - //tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); - //tent->s.clientNum = ent->s.clientNum; } /* @@ -863,7 +858,7 @@ static void ClientCleanName( const char *in, char *out, int outSize ) colorlessLen++; len++; } - + *out = 0; // don't allow empty names @@ -894,7 +889,7 @@ static qboolean G_NonSegModel( const char *filename ) G_Printf( "File not found: %s\n", filename ); return qfalse; } - + if( len <= 0 ) return qfalse; @@ -903,7 +898,7 @@ static qboolean G_NonSegModel( const char *filename ) G_Printf( "File %s too long\n", filename ); return qfalse; } - + trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); @@ -915,7 +910,7 @@ static qboolean G_NonSegModel( const char *filename ) while( 1 ) { token = COM_Parse( &text_p ); - + //EOF if( !token[ 0 ] ) break; @@ -966,13 +961,13 @@ void ClientUserinfoChanged( int clientNum ) // check for local client s = Info_ValueForKey( userinfo, "ip" ); - + if( !strcmp( s, "localhost" ) ) client->pers.localClient = qtrue; // check the item prediction s = Info_ValueForKey( userinfo, "cg_predictItems" ); - + if( !atoi( s ) ) client->pers.predictItemPickup = qfalse; else @@ -1001,7 +996,7 @@ void ClientUserinfoChanged( int clientNum ) // set max health health = atoi( Info_ValueForKey( userinfo, "handicap" ) ); client->pers.maxHealth = health; - + if( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) client->pers.maxHealth = 100; @@ -1046,7 +1041,7 @@ void ClientUserinfoChanged( int clientNum ) // wallwalk follow s = Info_ValueForKey( userinfo, "cg_wwFollow" ); - + if( atoi( s ) ) client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGFOLLOW; else @@ -1054,7 +1049,7 @@ void ClientUserinfoChanged( int clientNum ) // wallwalk toggle s = Info_ValueForKey( userinfo, "cg_wwToggle" ); - + if( atoi( s ) ) client->ps.persistant[ PERS_STATE ] |= PS_WALLCLIMBINGTOGGLE; else @@ -1062,7 +1057,7 @@ void ClientUserinfoChanged( int clientNum ) // teamInfo s = Info_ValueForKey( userinfo, "teamoverlay" ); - + if( ! *s || atoi( s ) != 0 ) client->pers.teamInfo = qtrue; else @@ -1083,7 +1078,7 @@ void ClientUserinfoChanged( int clientNum ) team = PTE_NONE; else team = client->ps.stats[ STAT_PTEAM ]; - + // send over a subset of the userinfo keys so other clients can // print scoreboards, display models, and play custom sounds s = va( "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d", @@ -1137,7 +1132,7 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) // check for a password value = Info_ValueForKey( userinfo, "password" ); - + if( g_password.string[ 0 ] && Q_stricmp( g_password.string, "none" ) && strcmp( g_password.string, value ) != 0 ) return "Invalid password"; @@ -1221,14 +1216,14 @@ void ClientBegin( int clientNum ) tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); tent->s.clientNum = ent->s.clientNum; } - + G_InitCommandQueue( clientNum ); G_SendCommandFromServer( -1, va( "print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname ) ); // request the clients PTR code G_SendCommandFromServer( ent - g_entities, "ptrcrequest" ); - + G_LogPrintf( "ClientBegin: %i\n", clientNum ); // count current clients and rank for scoreboard @@ -1262,7 +1257,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles vec3_t up = { 0.0f, 0.0f, 1.0f }; int maxAmmo, maxClips; weapon_t weapon; - + index = ent - g_entities; client = ent->client; @@ -1283,10 +1278,10 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles if( origin != NULL ) VectorCopy( origin, spawn_origin ); - + if( angles != NULL ) VectorCopy( angles, spawn_angles ); - + // find a spawn point // do it before setting health back up, so farthest // ranging doesn't count this client @@ -1308,7 +1303,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles } spawnPoint = spawn; - + if( ent != spawn ) { //start spawn animation on spawnPoint @@ -1331,21 +1326,21 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles saved = client->pers; savedSess = client->sess; savedPing = client->ps.ping; - + for( i = 0; i < MAX_PERSISTANT; i++ ) persistant[ i ] = client->ps.persistant[ i ]; - + eventSequence = client->ps.eventSequence; memset( client, 0, sizeof( *client ) ); - + client->pers = saved; client->sess = savedSess; client->ps.ping = savedPing; client->lastkilled_client = -1; - + for( i = 0; i < MAX_PERSISTANT; i++ ) client->ps.persistant[ i ] = persistant[ i ]; - + client->ps.eventSequence = eventSequence; // increment the spawncount so the client will detect the respawn @@ -1380,7 +1375,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles client->ps.eFlags = flags; client->ps.clientNum = index; - + BG_FindBBoxForClass( ent->client->pers.classSelection, ent->r.mins, ent->r.maxs, NULL, NULL, NULL ); if( client->sess.sessionTeam != TEAM_SPECTATOR ) @@ -1400,21 +1395,21 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles weapon = BG_FindStartWeaponForClass( ent->client->pers.classSelection ); else weapon = WP_NONE; - + BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips ); BG_AddWeaponToInventory( weapon, client->ps.stats ); BG_PackAmmoArray( weapon, client->ps.ammo, client->ps.powerups, maxAmmo, maxClips ); ent->client->ps.stats[ STAT_PCLASS ] = ent->client->pers.classSelection; ent->client->ps.stats[ STAT_PTEAM ] = ent->client->pers.teamSelection; - + ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE; ent->client->ps.stats[ STAT_STATE ] = 0; VectorSet( ent->client->ps.grapplePoint, 0.0f, 0.0f, 1.0f ); // health will count down towards max_health ent->health = client->ps.stats[ STAT_HEALTH ] = client->ps.stats[ STAT_MAX_HEALTH ]; //* 1.25; - + //if evolving scale health if( ent == spawn ) { @@ -1425,9 +1420,9 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles //clear the credits array for( i = 0; i < MAX_CLIENTS; i++ ) ent->credits[ i ] = 0; - + client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA; - + G_SetOrigin( ent, spawn_origin ); VectorCopy( spawn_origin, client->ps.origin ); @@ -1447,11 +1442,11 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles { spawn_angles[ YAW ] += 180.0f; AngleNormalize360( spawn_angles[ YAW ] ); - + if( spawnPoint->s.origin2[ 2 ] > 0.0f ) { vec3_t forward, dir; - + AngleVectors( spawn_angles, forward, NULL, NULL ); VectorScale( forward, F_VEL, forward ); VectorAdd( spawnPoint->s.origin2, forward, dir ); @@ -1459,7 +1454,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles VectorScale( dir, UP_VEL, client->ps.velocity ); } - + G_AddPredictableEvent( ent, EV_PLAYER_RESPAWN, 0 ); } } @@ -1511,7 +1506,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles // select the highest weapon number available, after any // spawn given items have fired client->ps.weapon = 1; - + for( i = WP_NUM_WEAPONS - 1; i > 0 ; i-- ) { if( BG_InventoryContainsWeapon( i, client->ps.stats ) ) @@ -1566,7 +1561,7 @@ void ClientDisconnect( int clientNum ) int i; ent = g_entities + clientNum; - + if( !ent->client ) return; |