Skip to content

Commit 947c5a1

Browse files
committed
Use different colors for different player traces
1 parent 9c0aa5f commit 947c5a1

3 files changed

Lines changed: 128 additions & 40 deletions

File tree

src/game/client/swarm/c_asw_marine.cpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,96 @@ extern ConVar rd_team_color_enemy;
108108
extern float g_fMarinePoisonDuration;
109109

110110
#ifdef CLIENT_DLL
111-
std::vector<bool> g_bShouldTracePlayer = std::vector<bool>(MAX_PLAYERS, false); // whether we have a trace position for this player
111+
Color g_TraceColorArray[8] =
112+
{
113+
Color(0, 0, 0, 255), // black (unused)
114+
Color(255, 255, 255, 255), // white
115+
Color(255, 255, 0, 255), // yellow
116+
Color(0, 255, 0, 255), // green
117+
Color(255, 0, 0, 255), // red
118+
Color(0, 0, 255, 255), // blue
119+
Color(255, 0, 255, 255), // pink
120+
Color(0, 255, 255, 255), // cyan
121+
};
122+
std::vector<int> g_nTracePlayer2Color = std::vector<int>(MAX_PLAYERS, 0);
123+
std::vector<int> g_nTraceColor2Player = std::vector<int>(8, 0);
112124
float TRACE_FADE_TIME = 60.0f; // how long to keep the trace positions for
113125
ConVar cl_trace_player_max_targets("cl_trace_player_max_targets", "3", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Maximum number of players to trace positions for in the client.", true, 1.0f, true, 7.0f);
114-
ConVar cl_trace_player_opacity("cl_trace_player_opacity", "0.5", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Opacity of the player trace positions in the client. 0.0 means fully transparent, 1.0 means fully opaque.", true, 0.0f, true, 1.0f);
126+
ConVar cl_trace_player_opacity("cl_trace_player_opacity", "1", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Opacity of the player trace positions in the client. 0.0 means fully transparent, 1.0 means fully opaque.", true, 0.0f, true, 1.0f);
127+
//ConVar cl_trace_player_line_thickness("cl_trace_player_line_thickness", "30", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Thickness of the player trace.", true, 1.0f, true, 100.0f);
128+
//ConVar cl_trace_player_border_thickness("cl_trace_player_border_thickness", "5", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Thickness of the player trace border.", true, 1.0f, true, 10.0f);
129+
130+
void RemoveInvalidTracePlayersAndColors()
131+
{
132+
for (int i = 1; i <= 7; i++)
133+
{
134+
// if this color's playerIndex is not a valid player, or if the color index is greater than the max targets, reset it
135+
if (g_nTraceColor2Player[i] <= 0 || g_nTraceColor2Player[i] >= MAX_PLAYERS || !UTIL_PlayerByIndex(g_nTraceColor2Player[i]) || i > cl_trace_player_max_targets.GetInt())
136+
{
137+
g_nTraceColor2Player[i] = 0;
138+
}
139+
}
140+
for (int i = 1; i < MAX_PLAYERS; i++)
141+
{
142+
// if this playerIndex is not a valid player, or if the player's colorIndex is greater than the max targets, reset it
143+
if (!UTIL_PlayerByIndex(i) || g_nTracePlayer2Color[i] <= 0 || g_nTracePlayer2Color[i] > cl_trace_player_max_targets.GetInt())
144+
{
145+
g_nTracePlayer2Color[i] = 0;
146+
}
147+
148+
}
149+
// cross-check the color -> player mapping, remove any record if not match
150+
for (int i = 1; i <= cl_trace_player_max_targets.GetInt(); i++)
151+
{
152+
if (g_nTracePlayer2Color[g_nTraceColor2Player[i]] != i)
153+
{
154+
g_nTraceColor2Player[i] = 0;
155+
}
156+
}
157+
// cross-check the player -> color mapping, remove any record if not match
158+
for (int i = 1; i < MAX_PLAYERS; i++)
159+
{
160+
if (g_nTraceColor2Player[g_nTracePlayer2Color[i]] != i)
161+
{
162+
g_nTracePlayer2Color[i] = 0;
163+
}
164+
}
165+
}
166+
167+
void ToggleTraceColor(int playerIndex)
168+
{
169+
RemoveInvalidTracePlayersAndColors();
170+
if ( playerIndex < 0 || playerIndex >= MAX_PLAYERS )
171+
return;
172+
int nColorIndex = g_nTracePlayer2Color[playerIndex];
173+
if ( nColorIndex != 0 )
174+
{
175+
g_nTracePlayer2Color[playerIndex] == 0;
176+
g_nTraceColor2Player[nColorIndex] = 0;
177+
}
178+
else
179+
{
180+
// find an available color index
181+
bool hasAvailableColor = false;
182+
for ( int i = 1; i <= cl_trace_player_max_targets.GetInt(); i++ )
183+
{
184+
if ( g_nTraceColor2Player[i] == 0 )
185+
{
186+
g_nTracePlayer2Color[playerIndex] = i;
187+
g_nTraceColor2Player[i] = playerIndex;
188+
hasAvailableColor = true;
189+
break;
190+
}
191+
}
192+
if(!hasAvailableColor)
193+
{
194+
// no available color, so replace the last one
195+
g_nTracePlayer2Color[g_nTraceColor2Player[cl_trace_player_max_targets.GetInt()]] = 0;
196+
g_nTraceColor2Player[cl_trace_player_max_targets.GetInt()] = playerIndex;
197+
g_nTracePlayer2Color[playerIndex] = cl_trace_player_max_targets.GetInt();
198+
}
199+
}
200+
}
115201
#endif
116202

117203
#define FLASHLIGHT_DISTANCE 1000

src/game/client/swarm/vgui/asw_hud_emotes.cpp

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@ using namespace vgui;
4545
extern ConVar asw_draw_hud;
4646

4747
#ifdef CLIENT_DLL
48-
extern std::vector<bool> g_bShouldTracePlayer;
4948
extern float TRACE_FADE_TIME;
5049
extern ConVar cl_trace_player_opacity;
50+
extern ConVar cl_trace_player_max_targets;
51+
//extern ConVar cl_trace_player_line_thickness;
52+
//extern ConVar cl_trace_player_border_thickness;
53+
extern Color g_TraceColorArray[8];
54+
extern std::vector<int> g_nTracePlayer2Color;
55+
extern std::vector<int> g_nTraceColor2Player;
56+
extern void RemoveInvalidTracePlayersAndColors();
57+
extern void ToggleTraceColor(int playerIndex);
5158
#endif
5259

5360
//-----------------------------------------------------------------------------
@@ -69,7 +76,7 @@ class CASWHudEmotes : public CASW_HudElement, public vgui::Panel
6976
virtual bool ShouldDraw( void ) { return asw_draw_hud.GetBool() && CASW_HudElement::ShouldDraw(); }
7077

7178
virtual void PaintTraces();
72-
virtual void PaintTracesFor(C_ASW_Marine* pMarine);
79+
virtual void PaintTracesFor(C_ASW_Marine* pMarine, Color color);
7380

7481
CPanelAnimationVarAliasType( int, m_nMedicTexture, "MedicEmoteTexture", "vgui/swarm/Emotes/EmoteMedic", "textureid" );
7582
CPanelAnimationVarAliasType( int, m_nAmmoTexture, "AmmoEmoteTexture", "vgui/swarm/Emotes/EmoteAmmo", "textureid" );
@@ -296,6 +303,7 @@ void CASWHudEmotes::PaintEmote( C_BaseEntity *pEnt, float fTime, int iTexture, f
296303

297304
void CASWHudEmotes::PaintTraces()
298305
{
306+
RemoveInvalidTracePlayersAndColors();
299307
C_ASW_Game_Resource* pGameResource = ASWGameResource();
300308
if (!pGameResource)
301309
return;
@@ -307,22 +315,22 @@ void CASWHudEmotes::PaintTraces()
307315
continue;
308316

309317
C_ASW_Marine* marine = pMR->GetMarineEntity();
310-
if (!pMR->IsInhabited() || !marine || !g_bShouldTracePlayer[pMR->GetCommanderIndex()])
318+
if (!pMR->IsInhabited() || !marine || g_nTracePlayer2Color[pMR->GetCommanderIndex()] == 0)
311319
continue;
312320

313-
PaintTracesFor(marine);
321+
PaintTracesFor(marine, g_TraceColorArray[g_nTracePlayer2Color[pMR->GetCommanderIndex()]]);
314322
}
315323
}
316324

317-
void CASWHudEmotes::PaintTracesFor(C_ASW_Marine* pMarine)
325+
void CASWHudEmotes::PaintTracesFor(C_ASW_Marine* pMarine, Color color)
318326
{
319327
// Not sure if the engine is single threaded or not, meanwhile, the list is accessed form other places. Therefore, lock m_TraceLock, just in case we are accessing the list from multiple threads, preventing concurrent modification of m_lstTracePlayerMovementList. Can safely remove the lock if the engine is gauranteed to be single threaded.
320328
std::lock_guard<std::mutex> lock(pMarine->m_TraceLock);
321329

322330
float fTimeRatio = 1.0 - gpGlobals->curtime / 3.0 + (int)(gpGlobals->curtime / 3.0); // current time
323-
float fOpacity = cl_trace_player_opacity.GetFloat(); // default opacity for traces
331+
color[3] = 255 * pow(cl_trace_player_opacity.GetFloat(), 2.2);
324332
int omx, omy;
325-
float fAlpha, fTraceRatio, xPos, yPos;
333+
float xPos, yPos;
326334
float fScale = (ScreenHeight() / 768.0f);
327335
float HalfW = 16.0f * fScale;
328336
float HalfH = 16.0f * fScale;
@@ -332,41 +340,42 @@ void CASWHudEmotes::PaintTracesFor(C_ASW_Marine* pMarine)
332340

333341
ASWInput()->ASW_GetCameraLocation(C_ASW_Player::GetLocalASWPlayer(), vecCameraFocus, cameraAngle, omx, omy, false);
334342

343+
// draw trace lines
344+
surface()->DrawSetColor(color);
345+
for (int i = 0; i < pMarine->m_vecTraceInterpolated.size() - 2; i++)
346+
{
347+
Vector vecPosition = pMarine->m_vecTraceInterpolated[i].m_vecPosition;
348+
Vector vecPositionNext = pMarine->m_vecTraceInterpolated[i + 1].m_vecPosition;
349+
350+
if (!debugoverlay->ScreenPosition(vecPosition, screenPos) && !debugoverlay->ScreenPosition(vecPositionNext, screenPosNext))
351+
{
352+
surface()->DrawLine(screenPos[0], screenPos[1], screenPosNext[0], screenPosNext[1]);
353+
}
354+
}
355+
335356
// draw trace direction icons
357+
surface()->DrawSetColor(color);
358+
surface()->DrawSetTexture(m_nTraceTexture);
336359
for (auto iter = pMarine->m_vecTraceInterpolated.begin(); iter != pMarine->m_vecTraceInterpolated.end(); ++iter)
337360
{
338361
if (iter->m_flTimestamp < 0.0f || iter->m_flTimestamp + 1.0f > gpGlobals->curtime)
339362
{
340363
continue;
341364
}
342-
float fTraceRatio = iter->m_flTraceTime / TRACE_FADE_TIME;
343365
Vector vecPosition = iter->m_vecPosition;
344366

345-
if (fTraceRatio <= 0)
367+
if (iter->m_flTraceTime <= 0)
346368
{
347369
continue; // no trace to draw
348370
}
349371

350-
fAlpha = (fTraceRatio + fTimeRatio) - (int)(fTraceRatio + fTimeRatio);
351-
if (fAlpha > 1.0 / 3.0 || fAlpha <= 0.01)
352-
{
353-
//continue;
354-
}
355-
else
356-
{
357-
fAlpha = pow(3.0 * fAlpha, 2.2);
358-
}
359-
360372
if (!debugoverlay->ScreenPosition(vecPosition, screenPos))
361373
{
362374
xPos = screenPos[0];
363375
yPos = screenPos[1];
364376

365377
if (m_nTraceTexture != -1)
366378
{
367-
surface()->DrawSetColor(Color(255, 255, 255, 255.0f));
368-
surface()->DrawSetTexture(m_nTraceTexture);
369-
370379
QAngle angFacing(0, -iter->m_flAngleDegree + cameraAngle.y - 90, 0);
371380

372381
Vector vecCornerTL(-HalfW, -HalfH, 0);
@@ -397,17 +406,4 @@ void CASWHudEmotes::PaintTracesFor(C_ASW_Marine* pMarine)
397406
}
398407
}
399408
}
400-
401-
// draw trace lines
402-
for (int i = 0; i < pMarine->m_vecTraceInterpolated.size() - 2; i++)
403-
{
404-
Vector vecPosition = pMarine->m_vecTraceInterpolated[i].m_vecPosition;
405-
Vector vecPositionNext = pMarine->m_vecTraceInterpolated[i + 1].m_vecPosition;
406-
407-
if (!debugoverlay->ScreenPosition(vecPosition, screenPos) && !debugoverlay->ScreenPosition(vecPositionNext, screenPosNext))
408-
{
409-
surface()->DrawSetColor(Color(255, 255, 255, 255.0f));
410-
surface()->DrawLine(screenPos[0], screenPos[1], screenPosNext[0], screenPosNext[1]);
411-
}
412-
}
413409
}

src/game/client/swarm/vgui/nb_lobby_row.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@
2626
#include "tier0/memdbgon.h"
2727

2828
extern ConVar rd_legacy_ui;
29+
2930
#ifdef CLIENT_DLL
30-
extern std::vector<bool> g_bShouldTracePlayer;
31+
extern Color g_TraceColorArray[8];
32+
extern std::vector<int> g_nTracePlayer2Color;
33+
extern std::vector<int> g_nTraceColor2Player;
3134
extern ConVar cl_trace_player_max_targets;
35+
extern void RemoveInvalidTracePlayersAndColors();
36+
extern void ToggleTraceColor(int playerIndex);
3237
#endif
3338

3439
using namespace BaseModUI;
@@ -455,6 +460,7 @@ void CNB_Lobby_Row::UpdateDetails()
455460
}
456461

457462
if (m_pTracePlayerButton) {
463+
RemoveInvalidTracePlayersAndColors();
458464
// In online games, show the button only for other players (not local player, not bot, and occupied slot)
459465
if (!Briefing()
460466
|| Briefing()->IsOfflineGame()
@@ -634,6 +640,6 @@ void CNB_Lobby_Row::OnTracePlayerPressed()
634640
return; // Invalid player index
635641
}
636642
// flip the trace state for this player
637-
g_bShouldTracePlayer[playerIndex] = !g_bShouldTracePlayer[playerIndex];
638-
m_pTracePlayerButton->SetImage(CBitmapButton::BUTTON_ENABLED, g_bShouldTracePlayer[playerIndex] ? "vgui/briefing/trace_player_icon_on" : "vgui/briefing/trace_player_icon_off", color32{ 255, 255, 255, 255 });
643+
ToggleTraceColor(playerIndex);
644+
m_pTracePlayerButton->SetImage(CBitmapButton::BUTTON_ENABLED, (g_nTracePlayer2Color[playerIndex] == 0) ? "vgui/briefing/trace_player_icon_on" : "vgui/briefing/trace_player_icon_off", color32{ 255, 255, 255, 255 });
639645
}

0 commit comments

Comments
 (0)