From 01aee82bd49575f16b5701cf842f04e6b1ba7b3d Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Tue, 3 Sep 2002 01:57:18 +0000 Subject: * Large purge of legacy Q3A code * Removed Q3A team system * Removed "gametype" stuff * Removed items * Refactored buildable physics * Other general cleanups --- src/game/bg_pmove.c | 2 +- src/game/bg_public.h | 18 - src/game/g_active.c | 39 -- src/game/g_buildable.c | 66 +++ src/game/g_client.c | 99 +---- src/game/g_cmds.c | 1055 +++++++++++++----------------------------------- src/game/g_combat.c | 102 +---- src/game/g_local.h | 36 +- src/game/g_main.c | 591 ++++++++------------------- src/game/g_mover.c | 4 - src/game/g_physics.c | 187 +++++++++ src/game/g_session.c | 82 +--- src/game/g_spawn.c | 49 --- src/game/g_svcmds.c | 18 +- src/game/g_target.c | 78 ++-- src/game/g_team.c | 858 ++------------------------------------- src/game/g_trigger.c | 31 +- src/game/g_utils.c | 14 +- 18 files changed, 838 insertions(+), 2491 deletions(-) create mode 100644 src/game/g_physics.c (limited to 'src/game') diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index f3158199..e79a3a8c 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -1834,7 +1834,7 @@ static void PM_CheckDuck (void) BG_FindViewheightForClass( pm->ps->stats[ STAT_PCLASS ], &PCvh, &PCcvh ); //TA: iD bug? you can still crouch when you're a spectator - if( pm->ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) + if( pm->ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) PCcvh = PCvh; pm->mins[0] = PCmins[0]; diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 2fd58deb..97def1db 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -103,22 +103,6 @@ #error overflow: (CS_MAX) > MAX_CONFIGSTRINGS #endif -typedef enum { - GT_FFA, // free for all - GT_TOURNAMENT, // one on one tournament - GT_SINGLE_PLAYER, // single player ffa - - //-- team games go after this -- - - GT_TEAM, // team deathmatch - GT_CTF, // capture the flag - GT_1FCTF, - GT_OBELISK, - GT_HARVESTER, - - GT_MAX_GAME_TYPE -} gametype_t; - typedef enum { GENDER_MALE, GENDER_FEMALE, GENDER_NEUTER } gender_t; /* @@ -735,8 +719,6 @@ typedef struct animation_s { typedef enum { TEAM_FREE, - TEAM_HUMANS, - TEAM_ALIENS, TEAM_SPECTATOR, TEAM_NUM_TEAMS diff --git a/src/game/g_active.c b/src/game/g_active.c index 6e6b7f1b..cef172a5 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -663,38 +663,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) { FireWeapon3( ent ); break; - case EV_USE_ITEM1: // teleporter - // drop flags in CTF - item = NULL; - j = 0; - - /*if ( ent->client->ps.powerups[ PW_REDFLAG ] ) { - item = BG_FindItemForPowerup( PW_REDFLAG ); - i = PW_REDFLAG; - } else if ( ent->client->ps.powerups[ PW_BLUEFLAG ] ) { - item = BG_FindItemForPowerup( PW_BLUEFLAG ); - i = PW_BLUEFLAG; - }*/ - - if ( item ) { - drop = Drop_Item( ent, item, 0 ); - // decide how many seconds it has left - /*drop->count = ( ent->client->ps.powerups[ j ] - level.time ) / 1000;*/ - if ( drop->count < 1 ) { - drop->count = 1; - } - - /*ent->client->ps.powerups[ j ] = 0;*/ - } - - SelectSpawnPoint( ent->client->ps.origin, origin, angles ); - TeleportPlayer( ent, origin, angles ); - break; - - case EV_USE_ITEM2: // medkit - ent->health = ent->client->ps.stats[STAT_MAX_HEALTH]; - break; - default: break; } @@ -743,9 +711,6 @@ static int StuckInOtherClient(gentity_t *ent) { return qfalse; } -//TA: rip bots -//void BotTestSolid(vec3_t origin); - /* ============== SendPendingPredictableEvents @@ -1089,10 +1054,6 @@ void ClientThink_real( gentity_t *ent ) { // NOTE: now copy the exact origin over otherwise clients can be snapped into solid VectorCopy( ent->client->ps.origin, ent->r.currentOrigin ); - //test for solid areas in the AAS file - //TA: rip bots - //BotTestSolid(ent->r.currentOrigin); - // touch other objects ClientImpacts( ent, &pm ); diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 657aed73..93d5619d 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -2282,3 +2282,69 @@ void G_ValidateBuild( gentity_t *ent, buildable_t buildable ) break; } } + +/* +================ +FinishSpawningBuildable + +Traces down to find where an item should rest, instead of letting them +free fall from their spawn points +================ +*/ +void FinishSpawningBuildable( gentity_t *ent ) +{ + trace_t tr; + vec3_t dest; + gentity_t *built; + buildable_t buildable = ent->s.modelindex; + + built = G_buildItem( ent, buildable, ent->s.pos.trBase, ent->s.angles ); + G_FreeEntity( ent ); + + // drop to floor + if( buildable != BA_NONE && BG_FindTrajectoryForBuildable( buildable ) == TR_BUOYANCY ) + VectorSet( dest, built->s.origin[0], built->s.origin[1], built->s.origin[2] + 4096 ); + else + VectorSet( dest, built->s.origin[0], built->s.origin[1], built->s.origin[2] - 4096 ); + + trap_Trace( &tr, built->s.origin, built->r.mins, built->r.maxs, dest, built->s.number, built->clipmask ); + if( tr.startsolid ) + { + G_Printf ("FinishSpawningBuildable: %s startsolid at %s\n", built->classname, vtos(built->s.origin)); + G_FreeEntity( built ); + return; + } + + //point items in the correct direction + VectorCopy( tr.plane.normal, built->s.origin2 ); + + // allow to ride movers + built->s.groundEntityNum = tr.entityNum; + + G_SetOrigin( built, tr.endpos ); + + trap_LinkEntity( built ); +} + + +qboolean itemRegistered[MAX_ITEMS]; + +/* +============ +G_SpawnBuildable + +Sets the clipping size and plants the object on the floor. + +Items can't be immediately dropped to floor, because they might +be on an entity that hasn't spawned yet. +============ +*/ +void G_SpawnBuildable( gentity_t *ent, buildable_t buildable ) +{ + ent->s.modelindex = buildable; + + // some movers spawn on the second frame, so delay item + // spawns until the third frame so they can ride trains + ent->nextthink = level.time + FRAMETIME * 2; + ent->think = FinishSpawningBuildable; +} diff --git a/src/game/g_client.c b/src/game/g_client.c index ac5329fa..fc469041 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -858,52 +858,6 @@ int TeamLeader( int team ) { return -1; } - -/* -================ -PickTeam - -================ -*/ -team_t PickTeam( int ignoreClientNum ) { - int counts[TEAM_NUM_TEAMS]; - - counts[TEAM_ALIENS] = TeamCount( ignoreClientNum, TEAM_ALIENS ); - counts[TEAM_HUMANS] = TeamCount( ignoreClientNum, TEAM_HUMANS ); - - if ( counts[TEAM_ALIENS] > counts[TEAM_HUMANS] ) { - return TEAM_HUMANS; - } - if ( counts[TEAM_HUMANS] > counts[TEAM_ALIENS] ) { - return TEAM_ALIENS; - } - // equal team count, so join the team with the lowest score - if ( level.teamScores[TEAM_ALIENS] > level.teamScores[TEAM_HUMANS] ) { - return TEAM_HUMANS; - } - return TEAM_ALIENS; -} - -/* -=========== -ForceClientSkin - -Forces a client's skin (for teamplay) -=========== -*/ -/* -static void ForceClientSkin( gclient_t *client, char *model, const char *skin ) { - char *p; - - if ((p = Q_strrchr(model, '/')) != 0) { - *p = 0; - } - - Q_strcat(model, MAX_QPATH, "/"); - Q_strcat(model, MAX_QPATH, skin); -} -*/ - /* =========== ClientCheckName @@ -1172,15 +1126,6 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { } G_ReadSessionData( client ); - //TA: rip bots - /*if( isBot ) { - ent->r.svFlags |= SVF_BOT; - ent->inuse = qtrue; - if( !G_BotConnect( clientNum, !firstTime ) ) { - return "BotConnectfailed"; - } - }*/ - // get and distribute relevent paramters G_LogPrintf( "ClientConnect: %i\n", clientNum ); ClientUserinfoChanged( clientNum ); @@ -1190,11 +1135,6 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) { trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname) ); } - if ( g_gametype.integer >= GT_TEAM && - client->sess.sessionTeam != TEAM_SPECTATOR ) { - BroadcastTeamChange( client, -1 ); - } - // count current clients and rank for scoreboard CalculateRanks(); @@ -1218,13 +1158,6 @@ void ClientBegin( int clientNum ) { ent = g_entities + clientNum; - //TA: rip bots - /*if( ent->botDelayBegin ) { - G_QueueBotBegin( clientNum ); - ent->botDelayBegin = qfalse; - return; - }*/ - client = level.clients + clientNum; if ( ent->r.linked ) { @@ -1257,9 +1190,7 @@ void ClientBegin( int clientNum ) { tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); tent->s.clientNum = ent->s.clientNum; - if ( g_gametype.integer != GT_TOURNAMENT ) { - trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname) ); - } + trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname) ); } G_LogPrintf( "ClientBegin: %i\n", clientNum ); @@ -1321,11 +1252,11 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn ) if ( client->sess.sessionTeam == TEAM_SPECTATOR ) { if( teamLocal == PTE_NONE ) - spawnPoint = SelectSpectatorSpawnPoint ( spawn_origin, spawn_angles); + spawnPoint = SelectSpectatorSpawnPoint ( spawn_origin, spawn_angles ); else if( teamLocal == PTE_ALIENS ) - spawnPoint = SelectAlienLockSpawnPoint ( spawn_origin, spawn_angles); + spawnPoint = SelectAlienLockSpawnPoint ( spawn_origin, spawn_angles ); else if( teamLocal == PTE_HUMANS ) - spawnPoint = SelectHumanLockSpawnPoint ( spawn_origin, spawn_angles); + spawnPoint = SelectHumanLockSpawnPoint ( spawn_origin, spawn_angles ); } else { @@ -1576,15 +1507,6 @@ void ClientDisconnect( int clientNum ) { return; } - // stop any following clients - for ( i = 0 ; i < level.maxclients ; i++ ) { - if ( level.clients[i].sess.sessionTeam == TEAM_SPECTATOR - && level.clients[i].sess.spectatorState == SPECTATOR_FOLLOW - && level.clients[i].sess.spectatorClient == clientNum ) { - StopFollowing( &g_entities[i] ); - } - } - // send effect if they were completely connected if ( ent->client->pers.connected == CON_CONNECTED && ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { @@ -1598,14 +1520,6 @@ void ClientDisconnect( int clientNum ) { G_LogPrintf( "ClientDisconnect: %i\n", clientNum ); - // if we are playing in tourney mode and losing, give a win to the other player - if ( ( g_gametype.integer == GT_TOURNAMENT ) - && !level.intermissiontime - && !level.warmupTime && level.sortedClients[1] == clientNum ) { - level.clients[ level.sortedClients[0] ].sess.wins++; - ClientUserinfoChanged( level.sortedClients[0] ); - } - trap_UnlinkEntity (ent); ent->s.modelindex = 0; ent->inuse = qfalse; @@ -1617,9 +1531,4 @@ void ClientDisconnect( int clientNum ) { trap_SetConfigstring( CS_PLAYERS + clientNum, ""); CalculateRanks(); - - //TA: rip bots - /*if ( ent->r.svFlags & SVF_BOT ) { - BotAIShutdownClient( clientNum ); - }*/ } diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 3b789207..37cc866e 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -16,51 +16,55 @@ #include "g_local.h" -#include "../../ui/menudef.h" // for the voice chats +//#include "../../ui/menudef.h" // for the voice chats /* ================== -DeathmatchScoreboardMessage +ScoreboardMessage ================== */ -void DeathmatchScoreboardMessage( gentity_t *ent ) { - char entry[1024]; - char string[1400]; +void ScoreboardMessage( gentity_t *ent ) +{ + char entry[ 1024 ]; + char string[ 1400 ]; int stringlength; int i, j; gclient_t *cl; int numSorted; // send the latest information on all clients - string[0] = 0; + string[ 0 ] = 0; stringlength = 0; numSorted = level.numConnectedClients; - for (i=0 ; i < numSorted ; i++) { + for( i = 0; i < numSorted; i++ ) + { int ping; - cl = &level.clients[level.sortedClients[i]]; + cl = &level.clients[ level.sortedClients[ i ] ]; - if ( cl->pers.connected == CON_CONNECTING ) { + if( cl->pers.connected == CON_CONNECTING ) ping = -1; - } else { + else ping = cl->ps.ping < 999 ? cl->ps.ping : 999; - } - Com_sprintf (entry, sizeof(entry), - " %i %i %i %i", level.sortedClients[i], - cl->ps.persistant[PERS_SCORE], ping, (level.time - cl->pers.enterTime)/60000 ); - j = strlen(entry); - if (stringlength + j > 1024) + + Com_sprintf( entry, sizeof( entry ), + " %i %i %i %i", level.sortedClients[ i ], + cl->ps.persistant[ PERS_SCORE ], ping, ( level.time - cl->pers.enterTime ) / 60000 ); + + j = strlen( entry ); + + if( stringlength + j > 1024 ) break; - strcpy (string + stringlength, entry); + + strcpy( string + stringlength, entry ); stringlength += j; } - trap_SendServerCommand( ent-g_entities, va("scores %i %i %i%s", i, - level.teamScores[TEAM_HUMANS], level.teamScores[TEAM_ALIENS], - string ) ); + trap_SendServerCommand( ent-g_entities, va( "scores %i %i %i%s", i, + level.alienKills, level.humanKills, string ) ); } @@ -71,8 +75,9 @@ Cmd_Score_f Request current scoreboard information ================== */ -void Cmd_Score_f( gentity_t *ent ) { - DeathmatchScoreboardMessage( ent ); +void Cmd_Score_f( gentity_t *ent ) +{ + ScoreboardMessage( ent ); } @@ -100,29 +105,35 @@ qboolean CheatsOk( gentity_t *ent ) { ConcatArgs ================== */ -char *ConcatArgs( int start ) { - int i, c, tlen; - static char line[MAX_STRING_CHARS]; - int len; - char arg[MAX_STRING_CHARS]; +char *ConcatArgs( int start ) +{ + int i, c, tlen; + static char line[ MAX_STRING_CHARS ]; + int len; + char arg[ MAX_STRING_CHARS ]; len = 0; - c = trap_Argc(); - for ( i = start ; i < c ; i++ ) { + c = trap_Argc( ); + + for( i = start; i < c; i++ ) + { trap_Argv( i, arg, sizeof( arg ) ); tlen = strlen( arg ); - if ( len + tlen >= MAX_STRING_CHARS - 1 ) { + + if( len + tlen >= MAX_STRING_CHARS - 1 ) break; - } + memcpy( line + len, arg, tlen ); len += tlen; - if ( i != c - 1 ) { - line[len] = ' '; + + if( i != c - 1 ) + { + line[ len ] = ' '; len++; } } - line[len] = 0; + line[ len ] = 0; return line; } @@ -363,19 +374,12 @@ and sends over a command to the client to resize the view, hide the scoreboard, and take a special screenshot ================== */ -void Cmd_LevelShot_f( gentity_t *ent ) { - if ( !CheatsOk( ent ) ) { - return; - } - - // doesn't work in single player - if ( g_gametype.integer != 0 ) { - trap_SendServerCommand( ent-g_entities, - "print \"Must be in g_gametype 0 for levelshot\n\"" ); +void Cmd_LevelShot_f( gentity_t *ent ) +{ + if( !CheatsOk( ent ) ) return; - } - BeginIntermission(); + BeginIntermission( ); trap_SendServerCommand( ent-g_entities, "clientLevelShot" ); } @@ -404,8 +408,9 @@ void Cmd_TeamTask_f( gentity_t *ent ) { Cmd_Kill_f ================= */ -void Cmd_Kill_f( gentity_t *ent ) { - if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) +void Cmd_Kill_f( gentity_t *ent ) +{ + if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) return; if( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) @@ -425,167 +430,6 @@ void Cmd_Kill_f( gentity_t *ent ) { player_die (ent, ent, ent, 100000, MOD_SUICIDE); } -/* -================= -BroadCastTeamChange - -Let everyone know about a team change -================= -*/ -void BroadcastTeamChange( gclient_t *client, int oldTeam ) -{ - if ( client->sess.sessionTeam == TEAM_HUMANS ) { - trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the humans.\n\"", - client->pers.netname) ); - } else if ( client->sess.sessionTeam == TEAM_ALIENS ) { - trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the aliens.\n\"", - client->pers.netname)); - } else if ( client->sess.sessionTeam == TEAM_SPECTATOR && oldTeam != TEAM_SPECTATOR ) { - trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the spectators.\n\"", - client->pers.netname)); - } else if ( client->sess.sessionTeam == TEAM_FREE ) { - trap_SendServerCommand( -1, va("cp \"%s" S_COLOR_WHITE " joined the battle.\n\"", - client->pers.netname)); - } -} - -/* -================= -SetTeam -================= -*/ -void SetTeam( gentity_t *ent, char *s ) { - int team, oldTeam; - gclient_t *client; - int clientNum; - spectatorState_t specState; - int specClient; - - // - // see what change is requested - // - client = ent->client; - - clientNum = client - level.clients; - specClient = 0; - - specState = SPECTATOR_NOT; - if ( !Q_stricmp( s, "scoreboard" ) || !Q_stricmp( s, "score" ) ) { - team = TEAM_SPECTATOR; - specState = SPECTATOR_SCOREBOARD; - } else if ( !Q_stricmp( s, "follow1" ) ) { - team = TEAM_SPECTATOR; - specState = SPECTATOR_FOLLOW; - specClient = -1; - } else if ( !Q_stricmp( s, "follow2" ) ) { - team = TEAM_SPECTATOR; - specState = SPECTATOR_FOLLOW; - specClient = -2; - } else if ( !Q_stricmp( s, "spectator" ) || !Q_stricmp( s, "s" ) ) { - team = TEAM_SPECTATOR; - specState = SPECTATOR_FREE; - } else if ( g_gametype.integer >= GT_TEAM ) { - // if running a team game, assign player to one of the teams - specState = SPECTATOR_NOT; - if ( !Q_stricmp( s, "humans" ) || !Q_stricmp( s, "h" ) ) { - team = TEAM_HUMANS; - } else if ( !Q_stricmp( s, "aliens" ) || !Q_stricmp( s, "d" ) ) { - team = TEAM_ALIENS; - } else { - // pick the team with the least number of players - team = PickTeam( clientNum ); - } - - if ( g_teamForceBalance.integer ) { - int counts[TEAM_NUM_TEAMS]; - - counts[TEAM_ALIENS] = TeamCount( ent->client->ps.clientNum, TEAM_ALIENS ); - counts[TEAM_HUMANS] = TeamCount( ent->client->ps.clientNum, TEAM_HUMANS ); - - // We allow a spread of two - if ( team == TEAM_HUMANS && counts[TEAM_HUMANS] - counts[TEAM_ALIENS] > 1 ) { - trap_SendServerCommand( ent->client->ps.clientNum, - "cp \"Humans team has too many players.\n\"" ); - return; // ignore the request - } - if ( team == TEAM_ALIENS && counts[TEAM_ALIENS] - counts[TEAM_HUMANS] > 1 ) { - trap_SendServerCommand( ent->client->ps.clientNum, - "cp \"Aliens team has too many players.\n\"" ); - return; // ignore the request - } - - // It's ok, the team we are switching to has less or same number of players - } - - } else { - // force them to spectators if there aren't any spots free - team = TEAM_FREE; - } - - // override decision if limiting the players - if ( (g_gametype.integer == GT_TOURNAMENT) - && level.numNonSpectatorClients >= 2 ) { - team = TEAM_SPECTATOR; - } else if ( g_maxGameClients.integer > 0 && - level.numNonSpectatorClients >= g_maxGameClients.integer ) { - team = TEAM_SPECTATOR; - } - - // - // decide if we will allow the change - // - oldTeam = client->sess.sessionTeam; - if ( team == oldTeam && team != TEAM_SPECTATOR ) { - return; - } - - // - // execute the team change - // - - // he starts at 'base' - client->pers.teamState.state = TEAM_BEGIN; - if ( oldTeam != TEAM_SPECTATOR ) { - // Kill him (makes sure he loses flags, etc) - ent->flags &= ~FL_GODMODE; - ent->client->ps.stats[STAT_HEALTH] = ent->health = 0; - player_die (ent, ent, ent, 100000, MOD_SUICIDE); - - } - // they go to the end of the line for tournements - if ( team == TEAM_SPECTATOR ) { - client->sess.spectatorTime = level.time; - } - - client->sess.sessionTeam = team; - client->sess.spectatorState = specState; - client->sess.spectatorClient = specClient; - - BroadcastTeamChange( client, oldTeam ); - - // get and distribute relevent paramters - ClientUserinfoChanged( clientNum ); - - ClientBegin( clientNum ); -} - -/* -================= -StopFollowing - -If the client being followed leaves the game, or you just want to drop -to free floating spectator mode -================= -*/ -void StopFollowing( gentity_t *ent ) { - ent->client->ps.persistant[ PERS_TEAM ] = TEAM_SPECTATOR; - ent->client->sess.sessionTeam = TEAM_SPECTATOR; - ent->client->sess.spectatorState = SPECTATOR_FREE; - ent->client->ps.pm_flags &= ~PMF_FOLLOW; - ent->r.svFlags &= ~SVF_BOT; - ent->client->ps.clientNum = ent - g_entities; -} - /* ================= Cmd_Team_f @@ -630,198 +474,95 @@ void Cmd_Team_f( gentity_t *ent ) } -/* -================= -Cmd_Follow_f -================= -*/ -void Cmd_Follow_f( gentity_t *ent ) { - int i; - char arg[MAX_TOKEN_CHARS]; - - if ( trap_Argc() != 2 ) { - if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) { - StopFollowing( ent ); - } - return; - } - - trap_Argv( 1, arg, sizeof( arg ) ); - i = ClientNumberFromString( ent, arg ); - if ( i == -1 ) { - return; - } - - // can't follow self - if ( &level.clients[ i ] == ent->client ) { - return; - } - - // can't follow another spectator - if ( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) { - return; - } - - // if they are playing a tournement game, count as a loss - if ( ( g_gametype.integer == GT_TOURNAMENT ) - && ent->client->sess.sessionTeam == TEAM_FREE ) { - ent->client->sess.losses++; - } - - // first set them to spectator - if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { - SetTeam( ent, "spectator" ); - } - - ent->client->sess.spectatorState = SPECTATOR_FOLLOW; - ent->client->sess.spectatorClient = i; -} - -/* -================= -Cmd_FollowCycle_f -================= -*/ -void Cmd_FollowCycle_f( gentity_t *ent, int dir ) { - int clientnum; - int original; - - // if they are playing a tournement game, count as a loss - if ( ( g_gametype.integer == GT_TOURNAMENT ) - && ent->client->sess.sessionTeam == TEAM_FREE ) { - ent->client->sess.losses++; - } - // first set them to spectator - if ( ent->client->sess.spectatorState == SPECTATOR_NOT ) { - SetTeam( ent, "spectator" ); - } - - if ( dir != 1 && dir != -1 ) { - G_Error( "Cmd_FollowCycle_f: bad dir %i", dir ); - } - - clientnum = ent->client->sess.spectatorClient; - original = clientnum; - do { - clientnum += dir; - if ( clientnum >= level.maxclients ) { - clientnum = 0; - } - if ( clientnum < 0 ) { - clientnum = level.maxclients - 1; - } - - // can only follow connected clients - if ( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) { - continue; - } - - // can't follow another spectator - if ( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) { - continue; - } - - // this is good, we can use it - ent->client->sess.spectatorClient = clientnum; - ent->client->sess.spectatorState = SPECTATOR_FOLLOW; - return; - } while ( clientnum != original ); - - // leave it where it was -} - - /* ================== G_Say ================== */ -static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) { - if (!other) { - return; - } - if (!other->inuse) { +static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) +{ + if( !other ) return; - } - if (!other->client) { + + if( !other->inuse ) return; - } - if ( other->client->pers.connected != CON_CONNECTED ) { + + if( !other->client ) return; - } - if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) { + + if( other->client->pers.connected != CON_CONNECTED ) return; - } - // no chatting to players in tournements - if ( ( g_gametype.integer == GT_TOURNAMENT ) - && other->client->sess.sessionTeam == TEAM_FREE - && ent->client->sess.sessionTeam != TEAM_FREE ) { + + if( mode == SAY_TEAM && !OnSameTeam( ent, other ) ) return; - } - trap_SendServerCommand( other-g_entities, va("%s \"%s%c%c%s\"", + trap_SendServerCommand( other-g_entities, va( "%s \"%s%c%c%s\"", mode == SAY_TEAM ? "tchat" : "chat", - name, Q_COLOR_ESCAPE, color, message)); + name, Q_COLOR_ESCAPE, color, message ) ); } #define EC "\x19" -void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) { +void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) +{ int j; gentity_t *other; int color; - char name[64]; + char name[ 64 ]; // don't let text be too long for malicious reasons - char text[MAX_SAY_TEXT]; - char location[64]; - - if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) { - mode = SAY_ALL; - } - - switch ( mode ) { - default: - case SAY_ALL: - G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText ); - Com_sprintf (name, sizeof(name), "%s%c%c"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); - color = COLOR_GREEN; - break; - case SAY_TEAM: - G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText ); - if (Team_GetLocationMsg(ent, location, sizeof(location))) - Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC") (%s)"EC": ", - ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location); - else - Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC")"EC": ", - ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); - color = COLOR_CYAN; - break; - case SAY_TELL: - if (target && g_gametype.integer >= GT_TEAM && - target->client->sess.sessionTeam == ent->client->sess.sessionTeam && - Team_GetLocationMsg(ent, location, sizeof(location))) - Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"] (%s)"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); - else - Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"]"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); - color = COLOR_MAGENTA; - break; + char text[ MAX_SAY_TEXT ]; + char location[ 64 ]; + + switch( mode ) + { + default: + case SAY_ALL: + G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText ); + Com_sprintf( name, sizeof( name ), "%s%c%c"EC": ", ent->client->pers.netname, + Q_COLOR_ESCAPE, COLOR_WHITE ); + color = COLOR_GREEN; + break; + + case SAY_TEAM: + G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText ); + if( Team_GetLocationMsg( ent, location, sizeof( location ) ) ) + Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC") (%s)"EC": ", + ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); + else + Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC")"EC": ", + ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); + color = COLOR_CYAN; + break; + + case SAY_TELL: + if( target && + target->client->ps.stats[ STAT_PTEAM ] == ent->client->ps.stats[ STAT_PTEAM ] && + Team_GetLocationMsg( ent, location, sizeof( location ) ) ) + Com_sprintf( name, sizeof( name ), EC"[%s%c%c"EC"] (%s)"EC": ", + ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); + else + Com_sprintf( name, sizeof( name ), EC"[%s%c%c"EC"]"EC": ", + ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); + color = COLOR_MAGENTA; + break; } - Q_strncpyz( text, chatText, sizeof(text) ); + Q_strncpyz( text, chatText, sizeof( text ) ); - if ( target ) { + if( target ) + { G_SayTo( ent, target, mode, color, name, text ); return; } // echo the text to the console - if ( g_dedicated.integer ) { + if( g_dedicated.integer ) G_Printf( "%s%s\n", name, text); - } // send it to all the apropriate clients - for (j = 0; j < level.maxclients; j++) { - other = &g_entities[j]; + for( j = 0; j < level.maxclients; j++ ) + { + other = &g_entities[ j ]; G_SayTo( ent, other, mode, color, name, text ); } } @@ -832,21 +573,17 @@ void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) Cmd_Say_f ================== */ -static void Cmd_Say_f( gentity_t *ent, int mode, qboolean arg0 ) { +static void Cmd_Say_f( gentity_t *ent, int mode, qboolean arg0 ) +{ char *p; - if ( trap_Argc () < 2 && !arg0 ) { + if( trap_Argc( ) < 2 && !arg0 ) return; - } - if (arg0) - { + if( arg0 ) p = ConcatArgs( 0 ); - } else - { p = ConcatArgs( 1 ); - } G_Say( ent, NULL, mode, p ); } @@ -856,26 +593,25 @@ static void Cmd_Say_f( gentity_t *ent, int mode, qboolean arg0 ) { Cmd_Tell_f ================== */ -static void Cmd_Tell_f( gentity_t *ent ) { +static void Cmd_Tell_f( gentity_t *ent ) +{ int targetNum; gentity_t *target; char *p; char arg[MAX_TOKEN_CHARS]; - if ( trap_Argc () < 2 ) { + if( trap_Argc( ) < 2 ) return; - } trap_Argv( 1, arg, sizeof( arg ) ); targetNum = atoi( arg ); - if ( targetNum < 0 || targetNum >= level.maxclients ) { + + if( targetNum < 0 || targetNum >= level.maxclients ) return; - } - target = &g_entities[targetNum]; - if ( !target || !target->inuse || !target->client ) { + target = &g_entities[ targetNum ]; + if( !target || !target->inuse || !target->client ) return; - } p = ConcatArgs( 2 ); @@ -883,240 +619,8 @@ static void Cmd_Tell_f( gentity_t *ent ) { G_Say( ent, target, SAY_TELL, p ); // don't tell to the player self if it was already directed to this player // also don't send the chat back to a bot - if ( ent != target && !(ent->r.svFlags & SVF_BOT)) { + if( ent != target && !( ent->r.svFlags & SVF_BOT ) ) G_Say( ent, ent, SAY_TELL, p ); - } -} - - -static void G_VoiceTo( gentity_t *ent, gentity_t *other, int mode, const char *id, qboolean voiceonly ) { - int color; - char *cmd; - - if (!other) { - return; - } - if (!other->inuse) { - return; - } - if (!other->client) { - return; - } - if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) { - return; - } - // no chatting to players in tournements - if ( (g_gametype.integer == GT_TOURNAMENT )) { - return; - } - - if (mode == SAY_TEAM) { - color = COLOR_CYAN; - cmd = "vtchat"; - } - else if (mode == SAY_TELL) { - color = COLOR_MAGENTA; - cmd = "vtell"; - } - else { - color = COLOR_GREEN; - cmd = "vchat"; - } - - trap_SendServerCommand( other-g_entities, va("%s %d %d %d %s", cmd, voiceonly, ent->s.number, color, id)); -} - - -void G_Voice( gentity_t *ent, gentity_t *target, int mode, const char *id, qboolean voiceonly ) { - int j; - gentity_t *other; - - if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) { - mode = SAY_ALL; - } - - if ( target ) { - G_VoiceTo( ent, target, mode, id, voiceonly ); - return; - } - - // echo the text to the console - if ( g_dedicated.integer ) { - G_Printf( "voice: %s %s\n", ent->client->pers.netname, id); - } - - // send it to all the apropriate clients - for (j = 0; j < level.maxclients; j++) { - other = &g_entities[j]; - G_VoiceTo( ent, other, mode, id, voiceonly ); - } -} - - -/* -================== -Cmd_Voice_f -================== -*/ -static void Cmd_Voice_f( gentity_t *ent, int mode, qboolean arg0, qboolean voiceonly ) { - char *p; - - if ( trap_Argc () < 2 && !arg0 ) { - return; - } - - if (arg0) - { - p = ConcatArgs( 0 ); - } - else - { - p = ConcatArgs( 1 ); - } - - G_Voice( ent, NULL, mode, p, voiceonly ); -} - - -/* -================== -Cmd_VoiceTell_f -================== -*/ -static void Cmd_VoiceTell_f( gentity_t *ent, qboolean voiceonly ) { - int targetNum; - gentity_t *target; - char *id; - char arg[MAX_TOKEN_CHARS]; - - if ( trap_Argc () < 2 ) { - return; - } - - trap_Argv( 1, arg, sizeof( arg ) ); - targetNum = atoi( arg ); - if ( targetNum < 0 || targetNum >= level.maxclients ) { - return; - } - - target = &g_entities[targetNum]; - if ( !target || !target->inuse || !target->client ) { - return; - } - - id = ConcatArgs( 2 ); - - G_LogPrintf( "vtell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, id ); - G_Voice( ent, target, SAY_TELL, id, voiceonly ); - // don't tell to the player self if it was already directed to this player - // also don't send the chat back to a bot - if ( ent != target && !(ent->r.svFlags & SVF_BOT)) { - G_Voice( ent, ent, SAY_TELL, id, voiceonly ); - } -} - - -/* -================== -Cmd_VoiceTaunt_f -================== -*/ -static void Cmd_VoiceTaunt_f( gentity_t *ent ) { - gentity_t *who; - int i; - - if (!ent->client) { - return; - } - - // insult someone who just killed you - if (ent->enemy && ent->enemy->client && ent->enemy->client->lastkilled_client == ent->s.number) { - // i am a dead corpse - if (!(ent->enemy->r.svFlags & SVF_BOT)) { - //G_Voice( ent, ent->enemy, SAY_TELL, VOICECHAT_DEATHINSULT, qfalse ); - } - if (!(ent->r.svFlags & SVF_BOT)) { - //G_Voice( ent, ent, SAY_TELL, VOICECHAT_DEATHINSULT, qfalse ); - } - ent->enemy = NULL; - return; - } - // insult someone you just killed - if (ent->client->lastkilled_client >= 0 && ent->client->lastkilled_client != ent->s.number) { - who = g_entities + ent->client->lastkilled_client; - if (who->client) { - // who is the person I just killed - if (who->client->lasthurt_mod == MOD_GAUNTLET) { - if (!(who->r.svFlags & SVF_BOT)) { - //G_Voice( ent, who, SAY_TELL, VOICECHAT_KILLGAUNTLET, qfalse ); // and I killed them with a gauntlet - } - if (!(ent->r.svFlags & SVF_BOT)) { - //G_Voice( ent, ent, SAY_TELL, VOICECHAT_KILLGAUNTLET, qfalse ); - } - } else { - if (!(who->r.svFlags & SVF_BOT)) { - //G_Voice( ent, who, SAY_TELL, VOICECHAT_KILLINSULT, qfalse ); // and I killed them with something else - } - if (!(ent->r.svFlags & SVF_BOT)) { - //G_Voice( ent, ent, SAY_TELL, VOICECHAT_KILLINSULT, qfalse ); - } - } - ent->client->lastkilled_client = -1; - return; - } - } - - if (g_gametype.integer >= GT_TEAM) { - // praise a team mate who just got a reward - for(i = 0; i < MAX_CLIENTS; i++) { - who = g_entities + i; - if (who->client && who != ent && who->client->sess.sessionTeam == ent->client->sess.sessionTeam) { - if (who->client->rewardTime > level.time) { - if (!(who->r.svFlags & SVF_BOT)) { - //G_Voice( ent, who, SAY_TELL, VOICECHAT_PRAISE, qfalse ); - } - if (!(ent->r.svFlags & SVF_BOT)) { - //G_Voice( ent, ent, SAY_TELL, VOICECHAT_PRAISE, qfalse ); - } - return; - } - } - } - } - - // just say something - //G_Voice( ent, NULL, SAY_ALL, VOICECHAT_TAUNT, qfalse ); -} - - -static char *gc_orders[] = { - "hold your position", - "hold this position", - "come here", - "cover me", - "guard location", - "search and destroy", - "report" -}; - -void Cmd_GameCommand_f( gentity_t *ent ) { - int player; - int order; - char str[MAX_TOKEN_CHARS]; - - trap_Argv( 1, str, sizeof( str ) ); - player = atoi( str ); - trap_Argv( 2, str, sizeof( str ) ); - order = atoi( str ); - - if ( player < 0 || player >= MAX_CLIENTS ) { - return; - } - if ( order < 0 || order > sizeof(gc_orders)/sizeof(char *) ) { - return; - } - G_Say( ent, &g_entities[player], SAY_TELL, gc_orders[order] ); - G_Say( ent, ent, SAY_TELL, gc_orders[order] ); } /* @@ -1144,25 +648,32 @@ static const char *gameNames[] = { Cmd_CallVote_f ================== */ -void Cmd_CallVote_f( gentity_t *ent ) { +void Cmd_CallVote_f( gentity_t *ent ) +{ int i; - char arg1[MAX_STRING_TOKENS]; - char arg2[MAX_STRING_TOKENS]; + char arg1[ MAX_STRING_TOKENS ]; + char arg2[ MAX_STRING_TOKENS ]; - if ( !g_allowVote.integer ) { + if( !g_allowVote.integer ) + { trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" ); return; } - if ( level.voteTime ) { + if( level.voteTime ) + { trap_SendServerCommand( ent-g_entities, "print \"A vote is already in progress.\n\"" ); return; } - if ( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) { + + if( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) + { trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of votes.\n\"" ); return; } - if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { + + if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_NONE ) + { trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" ); return; } @@ -1171,85 +682,86 @@ void Cmd_CallVote_f( gentity_t *ent ) { trap_Argv( 1, arg1, sizeof( arg1 ) ); trap_Argv( 2, arg2, sizeof( arg2 ) ); - if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) { + if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) + { trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" ); return; } - if ( !Q_stricmp( arg1, "map_restart" ) ) { - } else if ( !Q_stricmp( arg1, "nextmap" ) ) { - } else if ( !Q_stricmp( arg1, "map" ) ) { - } else if ( !Q_stricmp( arg1, "g_gametype" ) ) { - } else if ( !Q_stricmp( arg1, "kick" ) ) { - } else if ( !Q_stricmp( arg1, "clientkick" ) ) { - } else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) { - } else if ( !Q_stricmp( arg1, "timelimit" ) ) { - } else if ( !Q_stricmp( arg1, "fraglimit" ) ) { - } else { + if( !Q_stricmp( arg1, "map_restart" ) ) { } + else if( !Q_stricmp( arg1, "nextmap" ) ) { } + else if( !Q_stricmp( arg1, "map" ) ) { } + else if( !Q_stricmp( arg1, "kick" ) ) { } + else if( !Q_stricmp( arg1, "clientkick" ) ) { } + else if( !Q_stricmp( arg1, "timelimit" ) ) { } + else + { trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" ); - trap_SendServerCommand( ent-g_entities, "print \"Vote commands are: map_restart, nextmap, map , g_gametype , kick , clientkick , g_doWarmup, timelimit