summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Schwarz <lakitu7@gmail.com>2009-10-14 18:57:42 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:16:50 +0000
commita85a677ab302b0dec0cb716e5c071305825df666 (patch)
tree2242121b83be2c3385789058beb39b0b68387176
parent17db07ae8addfb0952875e3af929ca83a08ba481 (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)
-rw-r--r--assets/ui/menudef.h1
-rw-r--r--assets/ui/tremulous_common_hud.h13
-rw-r--r--src/cgame/cg_draw.c139
-rw-r--r--src/cgame/cg_drawtools.c27
-rw-r--r--src/cgame/cg_local.h16
-rw-r--r--src/cgame/cg_main.c9
-rw-r--r--src/cgame/cg_servercmds.c19
-rw-r--r--src/game/bg_public.h5
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_main.c2
-rw-r--r--src/game/g_team.c133
11 files changed, 284 insertions, 83 deletions
diff --git a/assets/ui/menudef.h b/assets/ui/menudef.h
index f87fc34e..a5f77468 100644
--- a/assets/ui/menudef.h
+++ b/assets/ui/menudef.h
@@ -155,6 +155,7 @@ enum
CG_PLAYER_CHARGE_BAR,
CG_PLAYER_CROSSHAIR,
CG_PLAYER_LOCATION,
+ CG_TEAMOVERLAY,
CG_PLAYER_CREDITS_FRACTION,
CG_KILLER,
diff --git a/assets/ui/tremulous_common_hud.h b/assets/ui/tremulous_common_hud.h
index 51e5d62f..a5f53356 100644
--- a/assets/ui/tremulous_common_hud.h
+++ b/assets/ui/tremulous_common_hud.h
@@ -149,6 +149,19 @@ itemDef
background "ui/assets/forwardarrow.tga"
}
+//TEAM OVERLAY
+itemDef
+{
+ name "teamoverlay"
+ rect BORDER 120 160 128
+ style WINDOW_STYLE_EMPTY
+ visible MENU_TRUE
+ decoration
+ forecolor COMMON_HUD_R COMMON_HUD_G COMMON_HUD_B 0.75
+ textscale 1.0
+ ownerdraw CG_TEAMOVERLAY
+}
+
//SNAPSHOT
itemDef
{
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 18427b8a..2b74a3f9 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -30,11 +30,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
menuDef_t *menuScoreboard = NULL;
-int drawTeamOverlayModificationCount = -1;
-
-int sortedTeamPlayers[ TEAM_MAXOVERLAY ];
-int numSortedTeamPlayers;
-
static void CG_AlignText( rectDef_t *rect, const char *text, float scale,
float w, float h,
int align, int valign,
@@ -1622,6 +1617,123 @@ static void CG_DrawTimer( rectDef_t *rect, float text_x, float text_y,
/*
=================
+CG_DrawTeamOverlay
+=================
+*/
+
+static void CG_DrawTeamOverlay( rectDef_t *rect, float scale, vec4_t color )
+{
+ char *s;
+ int i;
+ float x = rect->x;
+ float y, dx;
+ clientInfo_t *ci, *pci;
+ vec4_t tcolor;
+ float iconSize = rect->h/8.0f;
+ float leftMargin = 4.0f;
+ float iconTopMargin = 2.0f;
+ float midSep = 2.0f;
+ float backgroundWidth = rect->w;
+ float fontScale = 0.30f;
+ int maxDisplayCount = 0;
+ int displayCount = 0;
+ weapon_t curWeapon = WP_NONE;
+
+ if( cg.predictedPlayerState.pm_type == PM_SPECTATOR )
+ return;
+
+ if( !cg_drawTeamOverlay.integer || !cg_teamOverlayMaxPlayers.integer )
+ return;
+
+ if( !cgs.teaminfoReceievedTime ) return;
+
+ pci = cgs.clientinfo + cg.snap->ps.clientNum;
+
+
+ for( i = 0; i < MAX_CLIENTS; i++ )
+ {
+ ci = cgs.clientinfo + i;
+ if( ci->infoValid && pci != ci && ci->team == pci->team)
+ maxDisplayCount++;
+ }
+
+ if( maxDisplayCount > cg_teamOverlayMaxPlayers.integer )
+ maxDisplayCount = cg_teamOverlayMaxPlayers.integer;
+
+ iconSize *= scale;
+ leftMargin *= scale;
+ iconTopMargin *= scale;
+ midSep *= scale;
+ backgroundWidth *= scale;
+ fontScale *= scale;
+
+ y = rect->y - (float) maxDisplayCount * ( iconSize / 2.0f );
+
+ tcolor[ 0 ] = 1.0f;
+ tcolor[ 1 ] = 1.0f;
+ tcolor[ 2 ] = 1.0f;
+ tcolor[ 3 ] = color[ 3 ];
+
+ for( i = 0; i < MAX_CLIENTS && displayCount < maxDisplayCount; i++ )
+ {
+ ci = cgs.clientinfo + i;
+
+ if( !ci->infoValid || pci == ci || ci->team != pci->team )
+ continue;
+
+ dx = 0.f;
+ trap_R_SetColor( color );
+ CG_DrawPic( x, y-iconSize+iconTopMargin, backgroundWidth,
+ iconSize, cgs.media.teamOverlayShader );
+ trap_R_SetColor( tcolor );
+ if( ci->health <= 0 || !ci->curWeaponClass )
+ {
+ dx = -iconSize;
+ s = va( "%s^7", ci->name );
+ }
+ else
+ {
+ if( ci->team == TEAM_HUMANS )
+ curWeapon = ci->curWeaponClass;
+ else if( ci->team == TEAM_ALIENS )
+ curWeapon = BG_Class( ci->curWeaponClass )->startWeapon;
+
+ CG_DrawPic( x+leftMargin, y-iconSize+iconTopMargin, iconSize, iconSize,
+ cg_weapons[ curWeapon ].weaponIcon );
+ if( cg.predictedPlayerState.stats[ STAT_TEAM ] == TEAM_HUMANS )
+ {
+ if( ci->upgrade != UP_NONE )
+ {
+ CG_DrawPic( x+iconSize+leftMargin, y-iconSize+iconTopMargin,
+ iconSize, iconSize, cg_upgrades[ ci->upgrade ].upgradeIcon );
+ dx = iconSize;
+ }
+ }
+ else
+ {
+ if( curWeapon == WP_ABUILD2 || curWeapon == WP_ALEVEL1_UPG ||
+ curWeapon == WP_ALEVEL2_UPG || curWeapon == WP_ALEVEL3_UPG )
+ {
+ CG_DrawPic( x+iconSize+leftMargin, y-iconSize+iconTopMargin,
+ iconSize, iconSize, cgs.media.upgradeClassIconShader );
+ dx = iconSize;
+ }
+ }
+ s = va( "%s^7 [^%c%d^7] ^7%s", ci->name,
+ CG_GetColorCharForHealth( i ),
+ ci->health,
+ CG_ConfigString( CS_LOCATIONS + ci->location ) );
+ }
+ trap_R_SetColor( NULL );
+ UI_Text_Paint( x+iconSize+leftMargin+midSep+dx, y, fontScale, tcolor, s,
+ 0, 0, ITEM_TEXTSTYLE_NORMAL );
+ y += iconSize;
+ displayCount++;
+ }
+}
+
+/*
+=================
CG_DrawClock
=================
*/
@@ -2244,10 +2356,20 @@ static void CG_DrawCrosshairNames( rectDef_t *rect, float scale, int textStyle )
return;
}
+ // add health from overlay info to the crosshair client name
name = cgs.clientinfo[ cg.crosshairClientNum ].name;
+ if( cg_teamOverlayUserinfo.integer &&
+ cg.snap->ps.stats[ STAT_TEAM ] != TEAM_NONE &&
+ cgs.teaminfoReceievedTime )
+ {
+ name = va( "%s ^7[^%c%d^7]", name,
+ CG_GetColorCharForHealth( cg.crosshairClientNum ),
+ cgs.clientinfo[ cg.crosshairClientNum ].health );
+ }
+
w = UI_Text_Width( name, scale, 0 );
- x = rect->x + rect->w / 2;
- UI_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
+ x = rect->x + rect->w / 2.0f;
+ UI_Text_Paint( x - w / 2.0f, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
trap_R_SetColor( NULL );
}
@@ -2440,6 +2562,9 @@ void CG_OwnerDraw( float x, float y, float w, float h, float text_x,
case CG_LAGOMETER:
CG_DrawLagometer( &rect, text_x, text_y, scale, foreColor );
break;
+ case CG_TEAMOVERLAY:
+ CG_DrawTeamOverlay( &rect, scale, foreColor );
+ break;
case CG_DEMO_PLAYBACK:
CG_DrawDemoPlayback( &rect, foreColor, shader );
diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c
index 7d32fa1d..17eb7ac6 100644
--- a/src/cgame/cg_drawtools.c
+++ b/src/cgame/cg_drawtools.c
@@ -403,3 +403,30 @@ char *CG_KeyBinding( const char *bind )
}
return key;
}
+
+/*
+=================
+CG_GetColorCharForHealth
+=================
+*/
+char CG_GetColorCharForHealth( int clientnum )
+{
+ char health_char = '2';
+ int healthPercent;
+ int maxHealth;
+ int curWeaponClass = cgs.clientinfo[ clientnum ].curWeaponClass;
+
+ if( cgs.clientinfo[ clientnum ].team == TEAM_ALIENS )
+ maxHealth = BG_Class( curWeaponClass )->health;
+ else
+ maxHealth = BG_Class( PCL_HUMAN )->health;
+
+ healthPercent = (int) ( 100.0f * (float) cgs.clientinfo[ clientnum ].health
+ / (float) maxHealth );
+
+ if( healthPercent < 33 )
+ health_char = '1';
+ else if( healthPercent < 67 )
+ health_char = '3';
+ return health_char;
+}
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index d14454a1..7302ac78 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -730,8 +730,8 @@ typedef struct
int score; // updated by score servercmds
int location; // location index for team mode
int health; // you only get this info about your teammates
- int armor;
- int curWeapon;
+ int upgrade;
+ int curWeaponClass; // sends current weapon for H, current class for A
int handicap;
@@ -1188,6 +1188,7 @@ typedef struct
qhandle_t scannerBlipShader;
qhandle_t scannerLineShader;
+ qhandle_t teamOverlayShader;
qhandle_t numberShaders[ 11 ];
@@ -1384,6 +1385,8 @@ typedef struct
clientInfo_t clientinfo[ MAX_CLIENTS ];
+ int teaminfoReceievedTime;
+
// corpse info
clientInfo_t corpseinfo[ MAX_CLIENTS ];
@@ -1440,6 +1443,9 @@ extern vmCvar_t cg_drawChargeBar;
extern vmCvar_t cg_drawCrosshair;
extern vmCvar_t cg_drawCrosshairNames;
extern vmCvar_t cg_crosshairSize;
+extern vmCvar_t cg_drawTeamOverlay;
+extern vmCvar_t cg_teamOverlayMaxPlayers;
+extern vmCvar_t cg_teamOverlayUserinfo;
extern vmCvar_t cg_draw2D;
extern vmCvar_t cg_animSpeed;
extern vmCvar_t cg_debugAnim;
@@ -1596,20 +1602,16 @@ int CG_DrawStrlen( const char *str );
float *CG_FadeColor( int startMsec, int totalMsec );
void CG_TileClear( void );
void CG_ColorForHealth( vec4_t hcolor );
-void CG_GetColorForHealth( int health, int armor, vec4_t hcolor );
-
void CG_DrawRect( float x, float y, float width, float height, float size, const float *color );
void CG_DrawSides(float x, float y, float w, float h, float size);
void CG_DrawTopBottom(float x, float y, float w, float h, float size);
qboolean CG_WorldToScreen( vec3_t point, float *x, float *y );
char *CG_KeyBinding( const char *bind );
-
+char CG_GetColorCharForHealth( int clientnum );
//
// cg_draw.c
//
-extern int sortedTeamPlayers[ TEAM_MAXOVERLAY ];
-extern int numSortedTeamPlayers;
void CG_AddLagometerFrameInfo( void );
void CG_AddLagometerSnapshotInfo( snapshot_t *snap );
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 89082cee..bd3acec5 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -153,8 +153,10 @@ vmCvar_t cg_synchronousClients;
vmCvar_t cg_stats;
vmCvar_t cg_paused;
vmCvar_t cg_blood;
-vmCvar_t cg_teamOverlayUserinfo;
vmCvar_t cg_teamChatsOnly;
+vmCvar_t cg_drawTeamOverlay;
+vmCvar_t cg_teamOverlayMaxPlayers;
+vmCvar_t cg_teamOverlayUserinfo;
vmCvar_t cg_noPrintDuplicate;
vmCvar_t cg_noVoiceChats;
vmCvar_t cg_noVoiceText;
@@ -270,6 +272,8 @@ static cvarTable_t cvarTable[ ] =
{ &cg_thirdPersonPitchFollow, "cg_thirdPersonPitchFollow", "0", 0 },
{ &cg_thirdPersonShoulderViewMode, "cg_thirdPersonShoulderViewMode", "1", CVAR_ARCHIVE },
{ &cg_stats, "cg_stats", "0", 0 },
+ { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "1", CVAR_ARCHIVE },
+ { &cg_teamOverlayMaxPlayers, "cg_teamOverlayMaxPlayers", "8", CVAR_ARCHIVE },
{ &cg_teamOverlayUserinfo, "teamoverlay", "1", CVAR_ARCHIVE|CVAR_USERINFO },
{ &cg_teamChatsOnly, "cg_teamChatsOnly", "0", CVAR_ARCHIVE },
{ &cg_noPrintDuplicate, "cg_noPrintDuplicate", "0", CVAR_ARCHIVE },
@@ -428,6 +432,7 @@ void CG_UpdateCvars( void )
// check for modications here
CG_SetUIVars( );
+
}
@@ -747,6 +752,8 @@ static void CG_RegisterGraphics( void )
cgs.media.scannerBlipShader = trap_R_RegisterShader( "gfx/2d/blip" );
cgs.media.scannerLineShader = trap_R_RegisterShader( "gfx/2d/stalk" );
+ cgs.media.teamOverlayShader = trap_R_RegisterShader( "gfx/2d/teamoverlay" );
+
cgs.media.tracerShader = trap_R_RegisterShader( "gfx/misc/tracer" );
cgs.media.backTileShader = trap_R_RegisterShader( "console" );
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 4c462fe6..cd590c40 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -79,17 +79,14 @@ CG_ParseTeamInfo
static void CG_ParseTeamInfo( void )
{
int i;
+ int count;
int client;
- numSortedTeamPlayers = atoi( CG_Argv( 1 ) );
- if( numSortedTeamPlayers < 0 || numSortedTeamPlayers > TEAM_MAXOVERLAY )
- {
- CG_Error( "CG_ParseTeamInfo: numSortedTeamPlayers out of range (%d)",
- numSortedTeamPlayers );
- return;
- }
+ count = atoi( CG_Argv( 1 ) );
- for( i = 0; i < numSortedTeamPlayers; i++ )
+ cgs.teaminfoReceievedTime = cg.time;
+
+ for( i = 0; i < count; i++ )
{
client = atoi( CG_Argv( i * 5 + 2 ) );
if( client < 0 || client >= MAX_CLIENTS )
@@ -98,12 +95,10 @@ static void CG_ParseTeamInfo( void )
return;
}
- sortedTeamPlayers[ i ] = client;
-
cgs.clientinfo[ client ].location = atoi( CG_Argv( i * 5 + 3 ) );
cgs.clientinfo[ client ].health = atoi( CG_Argv( i * 5 + 4 ) );
- cgs.clientinfo[ client ].armor = atoi( CG_Argv( i * 5 + 5 ) );
- cgs.clientinfo[ client ].curWeapon = atoi( CG_Argv( i * 5 + 6 ) );
+ cgs.clientinfo[ client ].curWeaponClass = atoi( CG_Argv( i * 5 + 5 ) );
+ cgs.clientinfo[ client ].upgrade = atoi( CG_Argv( i * 5 + 6 ) );
}
}
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 );
}
}