diff options
-rw-r--r-- | assets/ui/ingame_options.menu | 34 | ||||
-rw-r--r-- | src/cgame/cg_draw.c | 157 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 1 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 2 |
4 files changed, 160 insertions, 34 deletions
diff --git a/assets/ui/ingame_options.menu b/assets/ui/ingame_options.menu index ad601938..5c22cdf6 100644 --- a/assets/ui/ingame_options.menu +++ b/assets/ui/ingame_options.menu @@ -398,9 +398,10 @@ { name hud group optionsGrp - type ITEM_TYPE_YESNO + type ITEM_TYPE_MULTI text "Show Team Overlay:" cvar "cg_drawTeamOverlay" + cvarFloatList { "Off" 0 "All Teammates" 1 "Support Teammates" 2 "Nearby Teammates" 3 } rect CONTENT_X (CONTENT_Y+(5*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER @@ -418,10 +419,31 @@ { name hud group optionsGrp + type ITEM_TYPE_MULTI + text "Sort Team Overlay:" + cvar "cg_teamOverlaySortMode" + cvarFloatList { "None" 0 "Score" 1 "Weapon/Class" 2 } + rect CONTENT_X (CONTENT_Y+(6*ELEM_H)) CONTENT_W ELEM_H + textalign ALIGN_RIGHT + textvalign VALIGN_CENTER + textalignx CONTENT_OFF + textscale .25 + forecolor 1 1 1 1 + visible MENU_FALSE + action + { + play "sound/misc/menu1.wav"; + } + } + + itemDef + { + name hud + group optionsGrp type ITEM_TYPE_YESNO text "Show Gun:" cvar "cg_drawGun" - rect CONTENT_X (CONTENT_Y+(6*ELEM_H)) CONTENT_W ELEM_H + rect CONTENT_X (CONTENT_Y+(7*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER textalignx CONTENT_OFF @@ -442,7 +464,7 @@ text "Show Speed:" cvar "cg_drawspeed" cvarFloatList { "No" 0 "Text" 1 "Graph" 2 "Text + Graph" 3 "Text No-Z" 5 "Graph No-Z" 6 "Text + Graph No-Z" 7 } - rect CONTENT_X (CONTENT_Y+(7*ELEM_H)) CONTENT_W ELEM_H + rect CONTENT_X (CONTENT_Y+(8*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER textalignx CONTENT_OFF @@ -462,7 +484,7 @@ type ITEM_TYPE_YESNO text "Show FPS:" cvar "cg_drawFPS" - rect CONTENT_X (CONTENT_Y+(8*ELEM_H)) CONTENT_W ELEM_H + rect CONTENT_X (CONTENT_Y+(9*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER textalignx CONTENT_OFF @@ -482,7 +504,7 @@ type ITEM_TYPE_YESNO text "Show Timer:" cvar "cg_drawTimer" - rect CONTENT_X (CONTENT_Y+(9*ELEM_H)) CONTENT_W ELEM_H + rect CONTENT_X (CONTENT_Y+(10*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER textalignx CONTENT_OFF @@ -502,7 +524,7 @@ type ITEM_TYPE_YESNO text "Show Demo State:" cvar "cg_drawDemoState" - rect CONTENT_X (CONTENT_Y+(10*ELEM_H)) CONTENT_W ELEM_H + rect CONTENT_X (CONTENT_Y+(11*ELEM_H)) CONTENT_W ELEM_H textalign ALIGN_RIGHT textvalign VALIGN_CENTER textalignx CONTENT_OFF diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 6e6753f2..7d548b82 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -1646,34 +1646,84 @@ static void CG_DrawTimer( rectDef_t *rect, float text_x, float text_y, CG_DrawTeamOverlay ================= */ + +typedef enum +{ + TEAMOVERLAY_OFF, + TEAMOVERLAY_ALL, + TEAMOVERLAY_SUPPORT, + TEAMOVERLAY_NEARBY, +} teamOverlayMode_t; + +typedef enum +{ + TEAMOVERLAY_SORT_NONE, + TEAMOVERLAY_SORT_SCORE, + TEAMOVERLAY_SORT_WEAPONCLASS, +} teamOverlaySort_t; + +static int QDECL SortScore( const void *a, const void *b ) +{ + int na = *(int *)a; + int nb = *(int *)b; + + return( cgs.clientinfo[ nb ].score - cgs.clientinfo[ na ].score ); +} + +static int QDECL SortWeaponClass( const void *a, const void *b ) +{ + int out; + clientInfo_t *ca = cgs.clientinfo + *(int *)a; + clientInfo_t *cb = cgs.clientinfo + *(int *)b; + + out = cb->curWeaponClass - ca->curWeaponClass; + + // We want grangers on top. ckits are already on top without the special case. + if( ca->team == TEAM_ALIENS ) + { + if( ca->curWeaponClass == PCL_ALIEN_BUILDER0_UPG || + cb->curWeaponClass == PCL_ALIEN_BUILDER0_UPG || + ca->curWeaponClass == PCL_ALIEN_BUILDER0 || + cb->curWeaponClass == PCL_ALIEN_BUILDER0 ) + { + out = -out; + } + } + + return( out ); +} + static void CG_DrawTeamOverlay( rectDef_t *rect, float scale, vec4_t color ) { - char *s; - int i; - float x = rect->x; - float y; - 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; - float vPad = 0.0f; - float nameWidth = 0.5f * rect->w; - char name[ MAX_NAME_LENGTH + 2 ]; - int maxDisplayCount = 0; - int displayCount = 0; - float nameMaxX, nameMaxXCp; - float maxX = rect->x + rect->w; - float maxXCp = maxX; - weapon_t curWeapon = WP_NONE; + char *s; + int i; + float x = rect->x; + float y; + 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; + float vPad = 0.0f; + float nameWidth = 0.5f * rect->w; + char name[ MAX_NAME_LENGTH + 2 ]; + int maxDisplayCount = 0; + int displayCount = 0; + float nameMaxX, nameMaxXCp; + float maxX = rect->x + rect->w; + float maxXCp = maxX; + weapon_t curWeapon = WP_NONE; + teamOverlayMode_t mode = cg_drawTeamOverlay.integer; + teamOverlaySort_t sort = cg_teamOverlaySortMode.integer; + int displayClients[ MAX_CLIENTS ]; if( cg.predictedPlayerState.pm_type == PM_SPECTATOR ) return; - if( !cg_drawTeamOverlay.integer || !cg_teamOverlayMaxPlayers.integer ) + if( mode == TEAMOVERLAY_OFF || !cg_teamOverlayMaxPlayers.integer ) return; if( !cgs.teaminfoReceievedTime ) @@ -1685,11 +1735,62 @@ static void CG_DrawTeamOverlay( rectDef_t *rect, float scale, vec4_t color ) pci = cgs.clientinfo + cg.snap->ps.clientNum; - for( i = 0; i < MAX_CLIENTS; i++ ) + if( mode == TEAMOVERLAY_ALL || mode == TEAMOVERLAY_SUPPORT ) + { + for( i = 0; i < MAX_CLIENTS; i++ ) + { + ci = cgs.clientinfo + i; + if( ci->infoValid && pci != ci && ci->team == pci->team ) + { + if( mode == TEAMOVERLAY_ALL ) + displayClients[ maxDisplayCount++ ] = i; + else + { + if( ci->curWeaponClass == PCL_ALIEN_BUILDER0 || + ci->curWeaponClass == PCL_ALIEN_BUILDER0_UPG || + ci->curWeaponClass == PCL_ALIEN_LEVEL1 || + ci->curWeaponClass == PCL_ALIEN_LEVEL1_UPG || + ci->curWeaponClass == WP_ABUILD || + ci->curWeaponClass == WP_ABUILD2 ) + { + displayClients[ maxDisplayCount++ ] = i; + } + } + } + } + } + else // find nearby + { + for( i = 0; i < cg.snap->numEntities; i++ ) + { + centity_t *cent = &cg_entities[ cg.snap->entities[ i ].number ]; + vec3_t relOrigin = { 0.0f, 0.0f, 0.0f }; + int team = cent->currentState.misc & 0x00FF; + + if( cent->currentState.eType != ET_PLAYER || + team != pci->team || + cent->currentState.eFlags & EF_DEAD ) + { + continue; + } + + VectorSubtract( cent->lerpOrigin, cg.predictedPlayerState.origin, relOrigin ); + + if( VectorLength( relOrigin ) < HELMET_RANGE ) + displayClients[ maxDisplayCount++ ] = cg.snap->entities[ i ].number; + } + } + + // Sort + if( sort == TEAMOVERLAY_SORT_SCORE ) + { + qsort( displayClients, maxDisplayCount, + sizeof( displayClients[ 0 ] ), SortScore ); + } + else if( sort == TEAMOVERLAY_SORT_WEAPONCLASS ) { - ci = cgs.clientinfo + i; - if( ci->infoValid && pci != ci && ci->team == pci->team ) - maxDisplayCount++; + qsort( displayClients, maxDisplayCount, + sizeof( displayClients[ 0 ] ), SortWeaponClass ); } if( maxDisplayCount > cg_teamOverlayMaxPlayers.integer ) @@ -1713,7 +1814,7 @@ static void CG_DrawTeamOverlay( rectDef_t *rect, float scale, vec4_t color ) for( i = 0; i < MAX_CLIENTS && displayCount < maxDisplayCount; i++ ) { - ci = cgs.clientinfo + i; + ci = cgs.clientinfo + displayClients[ i ]; if( !ci->infoValid || pci == ci || ci->team != pci->team ) continue; @@ -1754,7 +1855,7 @@ static void CG_DrawTeamOverlay( rectDef_t *rect, float scale, vec4_t color ) } s = va( " [^%c%3d^7] ^7%s", - CG_GetColorCharForHealth( i ), + CG_GetColorCharForHealth( displayClients[ i ] ), ci->health, CG_ConfigString( CS_LOCATIONS + ci->location ) ); } diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 6bc011f7..04766f53 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1441,6 +1441,7 @@ extern vmCvar_t cg_drawCrosshair; extern vmCvar_t cg_drawCrosshairNames; extern vmCvar_t cg_crosshairSize; extern vmCvar_t cg_drawTeamOverlay; +extern vmCvar_t cg_teamOverlaySortMode; extern vmCvar_t cg_teamOverlayMaxPlayers; extern vmCvar_t cg_teamOverlayUserinfo; extern vmCvar_t cg_draw2D; diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index dd08e324..14c72945 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -156,6 +156,7 @@ vmCvar_t cg_paused; vmCvar_t cg_blood; vmCvar_t cg_teamChatsOnly; vmCvar_t cg_drawTeamOverlay; +vmCvar_t cg_teamOverlaySortMode; vmCvar_t cg_teamOverlayMaxPlayers; vmCvar_t cg_teamOverlayUserinfo; vmCvar_t cg_noPrintDuplicate; @@ -274,6 +275,7 @@ static cvarTable_t cvarTable[ ] = { &cg_thirdPersonShoulderViewMode, "cg_thirdPersonShoulderViewMode", "1", CVAR_ARCHIVE }, { &cg_stats, "cg_stats", "0", 0 }, { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "1", CVAR_ARCHIVE }, + { &cg_teamOverlaySortMode, "cg_teamOverlaySortMode", "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 }, |