diff options
author | Christopher Schwarz <lakitu7@gmail.com> | 2009-10-14 18:57:42 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:16:50 +0000 |
commit | a85a677ab302b0dec0cb716e5c071305825df666 (patch) | |
tree | 2242121b83be2c3385789058beb39b0b68387176 /src/game | |
parent | 17db07ae8addfb0952875e3af929ca83a08ba481 (diff) |
* (bug 2991) Add teamoverlay, an optional hud display showing names, health, class/equipment, and locations of teammates
- Disable with cg_drawTeamOverlay 0 or remove it from your hud
- Control number of teammates to show with cg_teamOverlayMaxPlayers
- When teamoverlay is enabled, show health of teammates next to their name when the crosshair is over them
- Servers who dislike gameplay effects or want to save on bandwidth use can use g_allowTeamOverlay 0 to disable the feature for players
- Special thanks to Risujin for bring this idea and the original patch to Tremulous
* Cache teaminfo on the server and send only when needed (Undeference)
* Increase frequency of sending updated teaminfo (Undeference)
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/bg_public.h | 5 | ||||
-rw-r--r-- | src/game/g_local.h | 3 | ||||
-rw-r--r-- | src/game/g_main.c | 2 | ||||
-rw-r--r-- | src/game/g_team.c | 133 |
4 files changed, 87 insertions, 56 deletions
diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 0d9a4838..d1cc4572 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -789,10 +789,7 @@ typedef struct animation_s #define ANIM_FORCEBIT 0x40 // Time between location updates -#define TEAM_LOCATION_UPDATE_TIME 1000 - -// How many players on the overlay -#define TEAM_MAXOVERLAY 32 +#define TEAM_LOCATION_UPDATE_TIME 500 // player classes typedef enum diff --git a/src/game/g_local.h b/src/game/g_local.h index c9d06285..f8c141ec 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -339,6 +339,8 @@ typedef struct int adminLevel; char voice[ MAX_VOICE_NAME_LEN ]; qboolean useUnlagged; + // keep track of other players' info for tinfo + char cinfo[ MAX_CLIENTS ][ 16 ]; } clientPersistant_t; #define MAX_UNLAGGED_MARKERS 10 @@ -1133,6 +1135,7 @@ extern vmCvar_t g_dretchPunt; extern vmCvar_t g_privateMessages; extern vmCvar_t g_specChat; extern vmCvar_t g_publicAdminMessages; +extern vmCvar_t g_allowTeamOverlay; void trap_Print( const char *fmt ); void trap_Error( const char *fmt ); diff --git a/src/game/g_main.c b/src/game/g_main.c index 1386afa2..7f104a15 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -138,6 +138,7 @@ vmCvar_t g_dretchPunt; vmCvar_t g_privateMessages; vmCvar_t g_specChat; vmCvar_t g_publicAdminMessages; +vmCvar_t g_allowTeamOverlay; vmCvar_t g_tag; @@ -264,6 +265,7 @@ static cvarTable_t gameCvarTable[ ] = { &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse }, { &g_specChat, "g_specChat", "1", CVAR_ARCHIVE, 0, qfalse }, { &g_publicAdminMessages, "g_publicAdminMessages", "1", CVAR_ARCHIVE, 0, qfalse }, + { &g_allowTeamOverlay, "g_allowTeamOverlay", "1", CVAR_ARCHIVE, 0, qtrue }, { &g_tag, "g_tag", "main", CVAR_INIT, 0, qfalse } }; diff --git a/src/game/g_team.c b/src/game/g_team.c index db55c625..dbaf2b40 100644 --- a/src/game/g_team.c +++ b/src/game/g_team.c @@ -240,6 +240,7 @@ void G_ChangeTeam( gentity_t *ent, team_t newTeam ) ent->s.number, newTeam, oldTeam, ent->client->pers.netname, BG_TeamName( newTeam ) ); } + TeamplayInfoMessage( ent ); } /* @@ -277,83 +278,112 @@ gentity_t *Team_GetLocation( gentity_t *ent ) /*---------------------------------------------------------------------------*/ -static int QDECL SortClients( const void *a, const void *b ) -{ - return *(int *)a - *(int *)b; -} - - /* ================== -TeamplayLocationsMessage +TeamplayInfoMessage Format: - clientNum location health armor weapon misc + clientNum location health weapon upgrade ================== */ void TeamplayInfoMessage( gentity_t *ent ) { - char entry[ 1024 ]; - char string[ 8192 ]; - int stringlength; - int i, j; + char entry[ 19 ], string[ 1143 ]; + int i, j, team, stringlength; + int sent = 0; gentity_t *player; - int cnt; - int h, a = 0; - int clients[ TEAM_MAXOVERLAY ]; + gclient_t *cl; + upgrade_t upgrade = UP_NONE; + int curWeaponClass = WP_NONE ; // sends weapon for humans, class for aliens + char *tmp; - if( ! ent->client->pers.teamInfo ) - return; + if( !g_allowTeamOverlay.integer ) + return; - // figure out what client should be on the display - // we are limited to 8, but we want to use the top eight players - // but in client order (so they don't keep changing position on the overlay) - for( i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++ ) - { - player = g_entities + level.sortedClients[ i ]; + if( !ent->client->pers.teamInfo ) + return; - if( player->inuse && player->client->ps.stats[ STAT_TEAM ] == - ent->client->ps.stats[ STAT_TEAM ] ) - clients[ cnt++ ] = level.sortedClients[ i ]; + if( ent->client->pers.teamSelection == TEAM_NONE ) + { + if( ent->client->sess.spectatorState == SPECTATOR_FREE || + ent->client->sess.spectatorClient < 0 ) + return; + team = g_entities[ ent->client->sess.spectatorClient ].client-> + pers.teamSelection; } + else + team = ent->client->pers.teamSelection; - // We have the top eight players, sort them by clientNum - qsort( clients, cnt, sizeof( clients[ 0 ] ), SortClients ); - - // send the latest information on all clients - string[ 0 ] = 0; + string[ 0 ] = '\0'; stringlength = 0; - for( i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) + for( i = 0; i < MAX_CLIENTS; i++) { - player = g_entities + i; + player = g_entities + i ; + cl = player->client; + + if( ent == player || !cl || team != cl->pers.teamSelection || + !player->inuse ) + continue; - if( player->inuse && player->client->ps.stats[ STAT_TEAM ] == - ent->client->ps.stats[ STAT_TEAM ] ) + if( cl->sess.spectatorState != SPECTATOR_NOT ) { - h = player->client->ps.stats[ STAT_HEALTH ]; + curWeaponClass = WP_NONE; + upgrade = UP_NONE; + } + else if (cl->pers.teamSelection == TEAM_HUMANS ) + { + curWeaponClass = cl->ps.weapon; + + if( BG_InventoryContainsUpgrade( UP_BATTLESUIT, cl->ps.stats ) ) + upgrade = UP_BATTLESUIT; + else if( BG_InventoryContainsUpgrade( UP_JETPACK, cl->ps.stats ) ) + upgrade = UP_JETPACK; + else if( BG_InventoryContainsUpgrade( UP_BATTPACK, cl->ps.stats ) ) + upgrade = UP_BATTPACK; + else if( BG_InventoryContainsUpgrade( UP_HELMET, cl->ps.stats ) ) + upgrade = UP_HELMET; + else if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, cl->ps.stats ) ) + upgrade = UP_LIGHTARMOUR; + else + upgrade = UP_NONE; + } + else if( cl->pers.teamSelection == TEAM_ALIENS ) + { + curWeaponClass = cl->ps.stats[ STAT_CLASS ]; + upgrade = UP_NONE; + } + + tmp = va( "%i %i %i %i", + player->client->pers.location, + player->client->ps.stats[ STAT_HEALTH ] < 1 ? 0 : + player->client->ps.stats[ STAT_HEALTH ], + curWeaponClass, + upgrade ); + + if( !strcmp( ent->client->pers.cinfo[ i ], tmp ) ) + continue; - if( h < 0 ) - h = 0; + Q_strncpyz( ent->client->pers.cinfo[ i ], tmp, + sizeof( ent->client->pers.cinfo[ i ] ) ); - Com_sprintf( entry, sizeof( entry ), - " %i %i %i %i %i", - i, player->client->pers.location, h, a, - player->client->ps.weapon ); + Com_sprintf( entry, sizeof( entry ), " %i %s", i, tmp ); - j = strlen( entry ); + j = strlen( entry ); - if( stringlength + j > sizeof( string ) ) - break; + if( stringlength + j > sizeof( string ) ) + break; - strcpy( string + stringlength, entry ); - stringlength += j; - cnt++; - } + strcpy( string + stringlength, entry ); + stringlength += j; + sent++; } - trap_SendServerCommand( ent - g_entities, va( "tinfo %i%s", cnt, string ) ); + if( !sent ) + return; + + trap_SendServerCommand( ent - g_entities, va( "tinfo %i%s", sent, string ) ); } void CheckTeamStatus( void ) @@ -390,8 +420,7 @@ void CheckTeamStatus( void ) if( ent->client->pers.connected != CON_CONNECTED ) continue; - if( ent->inuse && ( ent->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS || - ent->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) ) + if( ent->inuse ) TeamplayInfoMessage( ent ); } } |