summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroy <tom_adams@web.de>2023-06-13 22:44:19 +0200
committerGitHub <noreply@github.com>2023-06-13 22:44:19 +0200
commitc0a7ad11c0daa49f517e028cb6f438b48995f346 (patch)
tree7b87a3f4c33608f61af19727f204ff0cb086e281
parent1343d1cd0e4cd5b01c6997d1d7ba0734c2dc33b8 (diff)
parente151238288942ffa18d196257423c54bd619ce3e (diff)
Merge pull request #3125 from Robyt3/CSpectator-fixes
Improve vertical centering and rectangle sizes in spectator UI, fix Free-View text color not being updated
-rw-r--r--src/game/client/components/spectator.cpp207
-rw-r--r--src/game/client/components/spectator.h1
-rw-r--r--src/game/client/render.h1
-rw-r--r--src/game/client/ui_rect.cpp5
-rw-r--r--src/game/client/ui_rect.h3
5 files changed, 105 insertions, 112 deletions
diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp
index ab7d4db4c..a9b28a3b3 100644
--- a/src/game/client/components/spectator.cpp
+++ b/src/game/client/components/spectator.cpp
@@ -14,38 +14,40 @@
#include "spectator.h"
+bool CSpectator::CanSpectate()
+{
+ return m_pClient->m_Snap.m_SpecInfo.m_Active
+ && (Client()->State() != IClient::STATE_DEMOPLAYBACK || DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER);
+}
void CSpectator::ConKeySpectator(IConsole::IResult *pResult, void *pUserData)
{
CSpectator *pSelf = (CSpectator *)pUserData;
- if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active &&
- (pSelf->Client()->State() != IClient::STATE_DEMOPLAYBACK || pSelf->DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER))
+ if(pSelf->CanSpectate())
pSelf->m_Active = pResult->GetInteger(0) != 0;
}
void CSpectator::ConSpectate(IConsole::IResult *pResult, void *pUserData)
{
CSpectator *pSelf = (CSpectator *)pUserData;
- if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active &&
- (pSelf->Client()->State() != IClient::STATE_DEMOPLAYBACK || pSelf->DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER))
+ if(pSelf->CanSpectate())
pSelf->Spectate(pResult->GetInteger(0), pResult->GetInteger(1));
}
bool CSpectator::SpecModePossible(int SpecMode, int SpectatorID)
{
- int i = SpectatorID;
switch(SpecMode)
{
case SPEC_PLAYER:
- if(!m_pClient->m_aClients[i].m_Active || m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
+ if(!m_pClient->m_aClients[SpectatorID].m_Active || m_pClient->m_aClients[SpectatorID].m_Team == TEAM_SPECTATORS)
{
return false;
}
if(m_pClient->m_LocalClientID != -1
&& m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != TEAM_SPECTATORS
- && (i == m_pClient->m_LocalClientID
- || m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != m_pClient->m_aClients[i].m_Team
- || (m_pClient->m_Snap.m_paPlayerInfos[i] && (m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD))))
+ && (SpectatorID == m_pClient->m_LocalClientID
+ || m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != m_pClient->m_aClients[SpectatorID].m_Team
+ || (m_pClient->m_Snap.m_paPlayerInfos[SpectatorID] && (m_pClient->m_Snap.m_paPlayerInfos[SpectatorID]->m_PlayerFlags&PLAYERFLAG_DEAD))))
{
return false;
}
@@ -173,13 +175,7 @@ void CSpectator::OnRender()
int TotalCount = 0;
for(int i = 0; i < MAX_CLIENTS; ++i)
{
- if(!m_pClient->m_Snap.m_paPlayerInfos[i]
- || m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS
- || (m_pClient->m_LocalClientID != -1
- && m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != TEAM_SPECTATORS
- && (m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD
- || m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != m_pClient->m_aClients[i].m_Team
- || i == m_pClient->m_LocalClientID)))
+ if(!SpecModePossible(SPEC_PLAYER, i))
continue;
TotalCount++;
}
@@ -198,166 +194,153 @@ void CSpectator::OnRender()
ScaleX = 1.5f;
// draw background
- const float Height = 400.0f * 3.0f;
- const float Width = Height * Graphics()->ScreenAspect();
+ const float ScreenHeight = 400.0f * 3.0f;
+ const float ScreenWidth = ScreenHeight * Graphics()->ScreenAspect();
+ Graphics()->MapScreen(0, 0, ScreenWidth, ScreenHeight);
- Graphics()->MapScreen(0, 0, Width, Height);
+ const float Height = 600.0f;
+ const float Width = 600.0f;
+ const float Margin = 20.0f;
- CUIRect Rect = {Width/2.0f-300.0f*ScaleX, Height/2.0f-300.0f, 600.0f*ScaleX, 600.0f};
+ const vec2 CenterOffset(ScreenWidth / 2.0f, ScreenHeight / 2.0f);
+ CUIRect BackgroundRect = {CenterOffset.x - Width / 2.0f * ScaleX, CenterOffset.y - Height / 2.0f, Width * ScaleX, Height};
Graphics()->BlendNormal();
- Rect.Draw(vec4(0.0f, 0.0f, 0.0f, 0.3f), 20.0f);
+ BackgroundRect.Draw(vec4(0.0f, 0.0f, 0.0f, 0.3f), Margin);
// clamp mouse position to selector area
- m_SelectorMouse.x = clamp(m_SelectorMouse.x, -300.0f*ScaleX + 20.0f, 300.0f*ScaleX - 20.0f);
- m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.0f);
+ m_SelectorMouse.x = clamp(m_SelectorMouse.x, -Width / 2.0f * ScaleX + Margin, Width / 2.0f * ScaleX - Margin);
+ m_SelectorMouse.y = clamp(m_SelectorMouse.y, -Height / 2.0f + Margin, Height / 2.0f - Margin);
- // draw selections
- float FontSize = 20.0f;
- float StartY = -210.0f+20.0f*ScaleY;
- float LineHeight = 60.0f*ScaleY;
- bool Selected = false;
+ const float FontSize = 20.0f;
+ // draw free-view selection
if(m_pClient->m_LocalClientID == -1 || m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team == TEAM_SPECTATORS)
{
+ CUIRect FreeViewRect;
+ FreeViewRect.x = CenterOffset.x - 280.0f;
+ FreeViewRect.y = CenterOffset.y - 280.0f;
+ FreeViewRect.w = 270.0f;
+ FreeViewRect.h = 60.0f;
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FREEVIEW)
- {
- Rect.x = Width/2.0f-280.0f;
- Rect.y = Height/2.0f-280.0f;
- Rect.w = 270.0f;
- Rect.h = 60.0f;
- Rect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 20.0f);
- }
+ FreeViewRect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 10.0f);
- if(m_SelectorMouse.x >= -280.0f && m_SelectorMouse.x <= -10.0f &&
- m_SelectorMouse.y >= -280.0f && m_SelectorMouse.y <= -220.0f)
- {
+ const bool Selected = FreeViewRect.Inside(m_SelectorMouse + CenterOffset);
+ if(Selected)
m_SelectedSpecMode = SPEC_FREEVIEW;
- Selected = true;
- }
- TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f);
+
+ TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected ? 1.0f : 0.5f);
static CTextCursor s_FreeViewLabelCursor;
+ s_FreeViewLabelCursor.m_Align = TEXTALIGN_ML;
s_FreeViewLabelCursor.m_FontSize = FontSize;
- s_FreeViewLabelCursor.MoveTo(Width/2.0f-240.0f, Height/2.0f-265.0f);
- s_FreeViewLabelCursor.Reset(g_Localization.Version());
+ s_FreeViewLabelCursor.MoveTo(FreeViewRect.x + 40.0f, FreeViewRect.y + FreeViewRect.h / 2.0f);
+ s_FreeViewLabelCursor.Reset((g_Localization.Version() << 1) | (Selected ? 1 : 0));
TextRender()->TextOutlined(&s_FreeViewLabelCursor, Localize("Free-View"), -1);
}
- //
- float x = 20.0f, y = -270;
- if (m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
+ // draw flag selection
+ float x = Margin, y = -270.0f;
+ if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
{
for(int Flag = SPEC_FLAGRED; Flag <= SPEC_FLAGBLUE; ++Flag)
{
+ CUIRect FlagRect;
+ FlagRect.x = CenterOffset.x + x - 10.0f;
+ FlagRect.y = CenterOffset.y + y - 10.0f;
+ FlagRect.w = 120.0f;
+ FlagRect.h = 60.0f;
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == Flag)
- {
- Rect.x = Width/2.0f+x-10.0f;
- Rect.y = Height/2.0f+y-10.0f;
- Rect.w = 120.0f;
- Rect.h = 60.0f;
- Rect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 20.0f);
- }
-
- Selected = false;
- if(m_SelectorMouse.x >= x-10.0f && m_SelectorMouse.x <= x+110.0f &&
- m_SelectorMouse.y >= y-10.0f && m_SelectorMouse.y <= y+50.0f)
- {
+ FlagRect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 10.0f);
+
+ const bool Selected = FlagRect.Inside(m_SelectorMouse + CenterOffset);
+ if(Selected)
m_SelectedSpecMode = Flag;
- Selected = true;
- }
+
+ const float Size = 60.0f / 1.5f + (Selected ? 12.0f : 8.0f);
+ const vec2 FlagSize = vec2(Size / 2.0f, Size);
+ const vec2 FlagPos = FlagRect.Center() - FlagSize / 2.0f;
Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
-
RenderTools()->SelectSprite(Flag == SPEC_FLAGRED ? SPRITE_FLAG_RED : SPRITE_FLAG_BLUE);
-
- float Size = 60.0f/1.5f + (Selected ? 12.0f : 8.0f);
- float FlagWidth = Width/2.0f + x + 40.0f + (Selected ? -3.0f : -2.0f);
- float FlagHeight = Height/2.0f + y + (Selected ? -6.0f : -4.0f);
-
- IGraphics::CQuadItem QuadItem(FlagWidth, FlagHeight, Size/2.0f, Size);
+ IGraphics::CQuadItem QuadItem(FlagPos.x, FlagPos.y, FlagSize.x, FlagSize.y);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
- x+=140.0f;
+ x += FlagRect.w + Margin;
}
}
- x = -300.0f*ScaleX + 30.0f, y = StartY;
+ const float PlayerStartY = -210.0f + Margin * ScaleY;
+ x = -Width / 2.0f * ScaleX + 30.0f, y = PlayerStartY;
+ // draw player selection
for(int i = 0, Count = 0; i < MAX_CLIENTS; ++i)
{
- if(!m_pClient->m_Snap.m_paPlayerInfos[i]
- || m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS
- || m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD
- || (m_pClient->m_LocalClientID != -1
- && m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != TEAM_SPECTATORS
- && (m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != m_pClient->m_aClients[i].m_Team || i == m_pClient->m_LocalClientID)))
+ if(!SpecModePossible(SPEC_PLAYER, i))
continue;
- if(Count != 0 && Count%ColumnSize == 0)
+ if(Count != 0 && Count % ColumnSize == 0)
{
x += 290.0f;
- y = StartY;
+ y = PlayerStartY;
}
Count++;
+ CUIRect PlayerRect;
+ PlayerRect.x = CenterOffset.x + x - 10.0f;
+ PlayerRect.y = CenterOffset.y + y + 10.0f - Margin * ScaleY;
+ PlayerRect.w = 270.0f;
+ PlayerRect.h = 60.0f * ScaleY;
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_PLAYER && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == i)
- {
- Rect.x = Width/2.0f+x-10.0f;
- Rect.y = Height/2.0f+y+10.0f-20.0f*ScaleY;
- Rect.w = 270.0f;
- Rect.h = 20.0f+40.0f*ScaleY;
- Rect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 20.0f);
- }
+ PlayerRect.Draw(vec4(1.0f, 1.0f, 1.0f, 0.25f), 10.0f);
- Selected = false;
- if(m_SelectorMouse.x >= x-10.0f && m_SelectorMouse.x <= x+260.0f &&
- m_SelectorMouse.y >= y-10.0f && m_SelectorMouse.y <= y-10.0f+LineHeight)
+ const bool Selected = PlayerRect.Inside(m_SelectorMouse + CenterOffset);
+ if(Selected)
{
m_SelectedSpecMode = SPEC_PLAYER;
m_SelectedSpectatorID = i;
- Selected = true;
}
- TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f);
- char aBuf[64];
- str_format(aBuf, sizeof(aBuf), "%s", Config()->m_ClShowsocial ? m_pClient->m_aClients[i].m_aName : "");
-
- static CTextCursor s_PlayerNameCursor;
- s_PlayerNameCursor.m_FontSize = FontSize;
- s_PlayerNameCursor.Reset();
-
- vec2 CursorPosition = vec2(Width/2.0f+x+50.0f, Height/2.0f+y+5.0f);
- CursorPosition.x += UI()->DrawClientID(s_PlayerNameCursor.m_FontSize, CursorPosition, i);
- s_PlayerNameCursor.MoveTo(CursorPosition.x, CursorPosition.y);
- TextRender()->TextOutlined(&s_PlayerNameCursor, aBuf, -1);
-
- // flag
- if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS &&
- m_pClient->m_Snap.m_pGameDataFlag && (m_pClient->m_Snap.m_pGameDataFlag->m_FlagCarrierRed == i ||
- m_pClient->m_Snap.m_pGameDataFlag->m_FlagCarrierBlue == i))
+
+ // carried flag
+ float PosX = PlayerRect.x + PlayerRect.h / 2.0f;
+ if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS
+ && m_pClient->m_Snap.m_pGameDataFlag
+ && (m_pClient->m_Snap.m_pGameDataFlag->m_FlagCarrierRed == i || m_pClient->m_Snap.m_pGameDataFlag->m_FlagCarrierBlue == i))
{
Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
-
RenderTools()->SelectSprite(i == m_pClient->m_Snap.m_pGameDataFlag->m_FlagCarrierBlue ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
-
- float Size = LineHeight;
- IGraphics::CQuadItem QuadItem(Width/2.0f+x+20.0f-Size/4.0f, Height/2.0f+y+20.0f-Size/1.5f, Size/2.0f, Size);
+ IGraphics::CQuadItem QuadItem(PosX - PlayerRect.h / 4.0f, PlayerRect.y - PlayerRect.h * 0.05f, PlayerRect.h / 2.0f, PlayerRect.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
}
+ // tee
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[i].m_RenderInfo;
TeeInfo.m_Size *= ScaleY;
- RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(Width/2.0f+x+20.0f, Height/2.0f+y+20.0f));
+ RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(PosX, PlayerRect.y + PlayerRect.h * 0.6f));
+ PosX += PlayerRect.h / 2.0f;
+
+ // client ID and name
+ PosX += UI()->DrawClientID(FontSize, vec2(PosX, PlayerRect.y + PlayerRect.h / 2.0f - FontSize * 0.6f), i);
+ if(Config()->m_ClShowsocial)
+ {
+ static CTextCursor s_PlayerNameCursor;
+ s_PlayerNameCursor.m_Align = TEXTALIGN_ML;
+ s_PlayerNameCursor.m_FontSize = FontSize;
+ s_PlayerNameCursor.Reset();
+ s_PlayerNameCursor.MoveTo(PosX, PlayerRect.y + PlayerRect.h / 2.0f);
+ TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected ? 1.0f : 0.5f);
+ TextRender()->TextOutlined(&s_PlayerNameCursor, m_pClient->m_aClients[i].m_aName, -1);
+ }
- y += LineHeight;
+ y += PlayerRect.h;
}
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
- RenderTools()->RenderCursor(m_SelectorMouse.x + Width/2.0f, m_SelectorMouse.y + Height/2.0f, 48.0f);
+ RenderTools()->RenderCursor(m_SelectorMouse + CenterOffset, 48.0f);
}
void CSpectator::OnReset()
diff --git a/src/game/client/components/spectator.h b/src/game/client/components/spectator.h
index 5aad68a7e..b55ac8ee6 100644
--- a/src/game/client/components/spectator.h
+++ b/src/game/client/components/spectator.h
@@ -20,6 +20,7 @@ class CSpectator : public CComponent
int m_SelectedSpecMode;
vec2 m_SelectorMouse;
+ bool CanSpectate();
bool SpecModePossible(int SpecMode, int SpectatorID);
void HandleSpectateNextPrev(int Direction);
diff --git a/src/game/client/render.h b/src/game/client/render.h
index 68c48c8a2..0e16a4e88 100644
--- a/src/game/client/render.h
+++ b/src/game/client/render.h
@@ -59,6 +59,7 @@ public:
void DrawSprite(float x, float y, float Size);
void RenderCursor(float CenterX, float CenterY, float Size);
+ void RenderCursor(vec2 Center, float Size) { RenderCursor(Center.x, Center.y, Size); }
// object render methods
void RenderTee(class CAnimState *pAnim, const CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos);
diff --git a/src/game/client/ui_rect.cpp b/src/game/client/ui_rect.cpp
index 6a3b35830..fd17ab522 100644
--- a/src/game/client/ui_rect.cpp
+++ b/src/game/client/ui_rect.cpp
@@ -10,6 +10,11 @@
const float CUIRect::s_CornerAnglePerSegment = 2 * NUM_ROUND_CORNER_SEGMENTS / pi;
IGraphics *CUIRect::s_pGraphics = 0;
+vec2 CUIRect::Center() const
+{
+ return vec2(x + w / 2.0f, y + h / 2.0f);
+}
+
void CUIRect::HSplitMid(CUIRect *pTop, CUIRect *pBottom, float Spacing) const
{
CUIRect r = *this;
diff --git a/src/game/client/ui_rect.h b/src/game/client/ui_rect.h
index cfef89294..88c45cce4 100644
--- a/src/game/client/ui_rect.h
+++ b/src/game/client/ui_rect.h
@@ -19,6 +19,8 @@ public:
float x, y, w, h;
+ vec2 Center() const;
+
void HSplitMid(CUIRect *pTop, CUIRect *pBottom, float Spacing = 0.0f) const;
void HSplitTop(float Cut, CUIRect *pTop, CUIRect *pBottom) const;
void HSplitBottom(float Cut, CUIRect *pTop, CUIRect *pBottom) const;
@@ -31,6 +33,7 @@ public:
void HMargin(float Cut, CUIRect *pOtherRect) const;
bool Inside(float x, float y) const;
+ bool Inside(vec2 Pos) const { return Inside(Pos.x, Pos.y); }
enum
{