2010-11-20 10:37:14 +00:00
|
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2010-09-07 17:03:59 +00:00
|
|
|
|
#include <engine/demo.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
|
#include <engine/graphics.h>
|
|
|
|
|
#include <engine/shared/config.h>
|
2020-09-26 19:41:58 +00:00
|
|
|
|
#include <engine/textrender.h>
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
|
|
|
|
#include <game/generated/protocol.h>
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
#include <game/client/animstate.h>
|
2011-03-19 17:28:47 +00:00
|
|
|
|
#include <game/client/components/countryflags.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
|
#include <game/client/components/motd.h>
|
2020-09-26 19:41:58 +00:00
|
|
|
|
#include <game/client/components/statboard.h>
|
|
|
|
|
#include <game/client/gameclient.h>
|
|
|
|
|
#include <game/client/render.h>
|
|
|
|
|
#include <game/localization.h>
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
#include "scoreboard.h"
|
|
|
|
|
|
|
|
|
|
CScoreboard::CScoreboard()
|
2008-08-27 19:50:33 +00:00
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
|
OnReset();
|
2008-08-27 19:50:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
|
void CScoreboard::ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData)
|
2008-08-27 19:50:33 +00:00
|
|
|
|
{
|
2011-01-06 04:45:53 +00:00
|
|
|
|
CScoreboard *pSelf = (CScoreboard *)pUserData;
|
|
|
|
|
pSelf->m_Active = pResult->GetInteger(0) != 0;
|
2008-08-27 19:50:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
void CScoreboard::OnReset()
|
2008-08-27 19:50:33 +00:00
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
|
m_Active = false;
|
2014-01-10 15:19:46 +00:00
|
|
|
|
m_ServerRecord = -1.0f;
|
2008-08-27 19:50:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-09-12 10:43:03 +00:00
|
|
|
|
void CScoreboard::OnRelease()
|
|
|
|
|
{
|
|
|
|
|
m_Active = false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-10 15:19:46 +00:00
|
|
|
|
void CScoreboard::OnMessage(int MsgType, void *pRawMsg)
|
|
|
|
|
{
|
2021-02-11 22:33:50 +00:00
|
|
|
|
if(MsgType == NETMSGTYPE_SV_RECORD || MsgType == NETMSGTYPE_SV_RECORDLEGACY)
|
2014-01-10 15:19:46 +00:00
|
|
|
|
{
|
|
|
|
|
CNetMsg_Sv_Record *pMsg = (CNetMsg_Sv_Record *)pRawMsg;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
m_ServerRecord = (float)pMsg->m_ServerTimeBest / 100;
|
2014-01-10 15:19:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
void CScoreboard::OnConsoleInit()
|
2008-08-27 19:50:33 +00:00
|
|
|
|
{
|
2011-08-13 00:11:06 +00:00
|
|
|
|
Console()->Register("+scoreboard", "", CFGFLAG_CLIENT, ConKeyScoreboard, this, "Show scoreboard");
|
2008-08-27 19:50:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
void CScoreboard::RenderGoals(float x, float y, float w)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
|
|
|
|
float h = 50.0f;
|
|
|
|
|
|
2022-07-09 14:54:13 +00:00
|
|
|
|
RenderTools()->DrawRect(x, y, w, h, ColorRGBA(0.0f, 0.0f, 0.0f, 0.5f), CUI::CORNER_ALL, 10.0f);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
|
|
// render goals
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj)
|
2008-09-07 15:07:08 +00:00
|
|
|
|
{
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit)
|
2010-05-29 07:25:38 +00:00
|
|
|
|
{
|
|
|
|
|
char aBuf[64];
|
2011-03-04 16:08:10 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%s: %d", Localize("Score limit"), m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + 10.0f, y + (h - 20.f) / 2.f, 20.0f, aBuf, -1.0f);
|
2010-05-29 07:25:38 +00:00
|
|
|
|
}
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit)
|
2010-05-29 07:25:38 +00:00
|
|
|
|
{
|
|
|
|
|
char aBuf[64];
|
2011-03-04 16:08:10 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), Localize("Time limit: %d min"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + 230.0f, y + (h - 20.f) / 2.f, 20.0f, aBuf, -1.0f);
|
2010-05-29 07:25:38 +00:00
|
|
|
|
}
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum && m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent)
|
2010-05-29 07:25:38 +00:00
|
|
|
|
{
|
|
|
|
|
char aBuf[64];
|
2011-03-04 16:08:10 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent, m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum);
|
2020-07-15 19:10:13 +00:00
|
|
|
|
float tw = TextRender()->TextWidth(0, 20.0f, aBuf, -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + w - tw - 10.0f, y + (h - 20.f) / 2.f, 20.0f, aBuf, -1.0f);
|
2010-05-29 07:25:38 +00:00
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-16 13:30:58 +00:00
|
|
|
|
void CScoreboard::RenderSpectators(float x, float y, float w, float h)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// background
|
2022-07-09 14:54:13 +00:00
|
|
|
|
RenderTools()->DrawRect(x, y, w, h, ColorRGBA(0.0f, 0.0f, 0.0f, 0.5f), CUI::CORNER_ALL, 10.0f);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
|
|
|
|
// Headline
|
|
|
|
|
y += 10.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + 10.0f, y + (30.f - 28.f) / 2.f, 28.0f, Localize("Spectators"), w - 20.0f);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
|
|
|
|
// spectator names
|
|
|
|
|
y += 30.0f;
|
|
|
|
|
bool Multiple = false;
|
2019-03-19 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
CTextCursor Cursor;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, x + 10.0f, y, 22.0f, TEXTFLAG_RENDER);
|
|
|
|
|
Cursor.m_LineWidth = w - 20.0f;
|
2019-03-19 07:12:56 +00:00
|
|
|
|
Cursor.m_MaxLines = 4;
|
|
|
|
|
|
2022-06-30 22:36:32 +00:00
|
|
|
|
for(const auto *pInfo : m_pClient->m_Snap.m_apInfoByName)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-03-19 17:28:47 +00:00
|
|
|
|
if(!pInfo || pInfo->m_Team != TEAM_SPECTATORS)
|
|
|
|
|
continue;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
if(Multiple)
|
2019-03-19 07:12:56 +00:00
|
|
|
|
TextRender()->TextEx(&Cursor, ", ", 2);
|
|
|
|
|
|
|
|
|
|
if(m_pClient->m_aClients[pInfo->m_ClientID].m_AuthLevel)
|
2019-03-19 14:37:17 +00:00
|
|
|
|
{
|
2019-04-26 12:06:32 +00:00
|
|
|
|
ColorRGBA Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClAuthedPlayerColor));
|
2019-04-26 22:34:20 +00:00
|
|
|
|
TextRender()->TextColor(Color);
|
2019-03-19 14:37:17 +00:00
|
|
|
|
}
|
2019-03-19 07:12:56 +00:00
|
|
|
|
|
2014-08-23 09:32:54 +00:00
|
|
|
|
if(g_Config.m_ClShowIDs)
|
|
|
|
|
{
|
2019-03-20 17:27:08 +00:00
|
|
|
|
char aBuffer[5];
|
2019-03-19 07:12:56 +00:00
|
|
|
|
int size = str_format(aBuffer, sizeof(aBuffer), "%d: ", pInfo->m_ClientID);
|
|
|
|
|
TextRender()->TextEx(&Cursor, aBuffer, size);
|
2014-08-23 09:32:54 +00:00
|
|
|
|
}
|
2019-03-19 07:12:56 +00:00
|
|
|
|
TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1);
|
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
Multiple = true;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-05 11:15:27 +00:00
|
|
|
|
void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const char *pTitle, int NumPlayers)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-01-11 22:03:01 +00:00
|
|
|
|
if(Team == TEAM_SPECTATORS)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-01-10 17:15:26 +00:00
|
|
|
|
bool lower16 = false;
|
2013-12-31 05:13:57 +00:00
|
|
|
|
bool upper16 = false;
|
2014-01-19 21:08:33 +00:00
|
|
|
|
bool lower24 = false;
|
|
|
|
|
bool upper24 = false;
|
2014-01-10 14:45:32 +00:00
|
|
|
|
bool lower32 = false;
|
|
|
|
|
bool upper32 = false;
|
2014-01-19 21:08:33 +00:00
|
|
|
|
|
2014-01-10 17:15:26 +00:00
|
|
|
|
if(Team == -3)
|
2013-12-31 05:13:57 +00:00
|
|
|
|
upper16 = true;
|
2014-01-10 17:15:26 +00:00
|
|
|
|
else if(Team == -4)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
lower32 = true;
|
2014-01-10 17:15:26 +00:00
|
|
|
|
else if(Team == -5)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
upper32 = true;
|
2014-01-10 17:15:26 +00:00
|
|
|
|
else if(Team == -6)
|
|
|
|
|
lower16 = true;
|
2014-01-19 21:08:33 +00:00
|
|
|
|
else if(Team == -7)
|
|
|
|
|
lower24 = true;
|
|
|
|
|
else if(Team == -8)
|
|
|
|
|
upper24 = true;
|
|
|
|
|
|
2021-02-21 11:18:07 +00:00
|
|
|
|
bool IsTeamplayTeam = Team > TEAM_SPECTATORS;
|
|
|
|
|
|
2014-01-19 21:08:33 +00:00
|
|
|
|
if(Team < -1)
|
2014-01-10 17:15:26 +00:00
|
|
|
|
Team = 0;
|
2013-12-31 05:13:57 +00:00
|
|
|
|
|
2020-11-07 17:36:24 +00:00
|
|
|
|
if(NumPlayers < 0)
|
|
|
|
|
NumPlayers = m_pClient->m_Snap.m_aTeamSize[Team];
|
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
float h = 760.0f;
|
2010-09-27 19:41:41 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// background
|
2022-07-09 14:54:13 +00:00
|
|
|
|
{
|
|
|
|
|
int Corners;
|
|
|
|
|
if(upper16 || upper32 || upper24)
|
|
|
|
|
Corners = CUI::CORNER_R;
|
|
|
|
|
else if(lower16 || lower32 || lower24)
|
|
|
|
|
Corners = CUI::CORNER_L;
|
|
|
|
|
else
|
|
|
|
|
Corners = CUI::CORNER_ALL;
|
|
|
|
|
RenderTools()->DrawRect(x, y, w, h, ColorRGBA(0.0f, 0.0f, 0.0f, 0.5f), Corners, 17.0f);
|
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2019-07-11 14:06:09 +00:00
|
|
|
|
char aBuf[128] = {0};
|
|
|
|
|
|
2008-08-27 15:48:50 +00:00
|
|
|
|
// render title
|
2011-03-19 17:28:47 +00:00
|
|
|
|
float TitleFontsize = 40.0f;
|
2020-12-31 09:03:15 +00:00
|
|
|
|
int TitleWidth = (lower32 || lower24 || lower16) ? 1140 : 440;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
if(!pTitle)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER)
|
2010-05-29 07:25:38 +00:00
|
|
|
|
pTitle = Localize("Game over");
|
2008-08-27 15:48:50 +00:00
|
|
|
|
else
|
2019-07-11 14:06:09 +00:00
|
|
|
|
{
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aBuf, Client()->GetCurrentMap());
|
2020-12-31 09:03:15 +00:00
|
|
|
|
while(TextRender()->TextWidth(0, TitleFontsize, aBuf, -1, -1.0f) > TitleWidth)
|
|
|
|
|
aBuf[str_length(aBuf) - 1] = '\0';
|
2020-08-02 11:45:20 +00:00
|
|
|
|
if(str_comp(aBuf, Client()->GetCurrentMap()))
|
|
|
|
|
str_append(aBuf, "…", sizeof(aBuf));
|
|
|
|
|
pTitle = aBuf;
|
2019-07-11 14:06:09 +00:00
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
2020-07-15 19:42:48 +00:00
|
|
|
|
TextRender()->Text(0, x + 20.0f, y + (50.f - TitleFontsize) / 2.f, TitleFontsize, pTitle, -1.0f);
|
2014-01-10 14:45:32 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS)
|
2011-03-04 16:08:10 +00:00
|
|
|
|
{
|
|
|
|
|
if(m_pClient->m_Snap.m_pGameDataObj)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-03-04 16:08:10 +00:00
|
|
|
|
int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue;
|
2011-01-12 09:08:17 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Score);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
2011-01-06 04:45:53 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-04-05 17:00:00 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW &&
|
2022-06-30 22:36:32 +00:00
|
|
|
|
m_pClient->m_Snap.m_apPlayerInfos[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID])
|
2011-04-05 17:00:00 +00:00
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
|
int Score = m_pClient->m_Snap.m_apPlayerInfos[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID]->m_Score;
|
2011-04-05 17:00:00 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Score);
|
|
|
|
|
}
|
|
|
|
|
else if(m_pClient->m_Snap.m_pLocalInfo)
|
2011-03-12 17:07:57 +00:00
|
|
|
|
{
|
|
|
|
|
int Score = m_pClient->m_Snap.m_pLocalInfo->m_Score;
|
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Score);
|
|
|
|
|
}
|
2011-01-06 04:45:53 +00:00
|
|
|
|
}
|
2014-01-10 15:19:46 +00:00
|
|
|
|
|
2019-06-04 22:44:59 +00:00
|
|
|
|
if(m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard)
|
2014-01-10 15:19:46 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_ServerRecord > 0)
|
2020-10-18 21:33:45 +00:00
|
|
|
|
str_time_float(m_ServerRecord, TIME_HOURS, aBuf, sizeof(aBuf));
|
2014-01-10 15:19:46 +00:00
|
|
|
|
else
|
|
|
|
|
aBuf[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-10 17:15:26 +00:00
|
|
|
|
float tw;
|
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(!lower16 && !lower32 && !lower24)
|
2014-01-10 17:15:26 +00:00
|
|
|
|
{
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, TitleFontsize, aBuf, -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + w - tw - 20.0f, y + (50.f - TitleFontsize) / 2.f, TitleFontsize, aBuf, -1.0f);
|
2014-01-10 17:15:26 +00:00
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// calculate measurements
|
|
|
|
|
float LineHeight = 60.0f;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
float TeeSizeMod = 1.0f;
|
2011-04-04 18:37:12 +00:00
|
|
|
|
float Spacing = 16.0f;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
float RoundRadius = 15.0f;
|
2020-11-05 11:15:27 +00:00
|
|
|
|
float FontSize = 24.0f;
|
|
|
|
|
if(NumPlayers > 48)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
{
|
|
|
|
|
LineHeight = 20.0f;
|
|
|
|
|
TeeSizeMod = 0.4f;
|
|
|
|
|
Spacing = 0.0f;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
RoundRadius = 5.0f;
|
2020-11-05 11:15:27 +00:00
|
|
|
|
FontSize = 16.0f;
|
2014-01-08 03:11:50 +00:00
|
|
|
|
}
|
2020-11-05 11:15:27 +00:00
|
|
|
|
else if(NumPlayers > 32)
|
2014-01-19 21:08:33 +00:00
|
|
|
|
{
|
|
|
|
|
LineHeight = 27.0f;
|
|
|
|
|
TeeSizeMod = 0.6f;
|
|
|
|
|
Spacing = 0.0f;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
RoundRadius = 5.0f;
|
2020-11-05 11:15:27 +00:00
|
|
|
|
FontSize = 20.0f;
|
2014-01-19 21:08:33 +00:00
|
|
|
|
}
|
2020-11-05 11:15:27 +00:00
|
|
|
|
else if(NumPlayers > 12)
|
2009-05-31 09:44:20 +00:00
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
|
LineHeight = 40.0f;
|
|
|
|
|
TeeSizeMod = 0.8f;
|
2011-03-19 17:28:47 +00:00
|
|
|
|
Spacing = 0.0f;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
RoundRadius = 15.0f;
|
2009-05-31 09:44:20 +00:00
|
|
|
|
}
|
2020-11-05 11:15:27 +00:00
|
|
|
|
else if(NumPlayers > 8)
|
2011-03-19 17:28:47 +00:00
|
|
|
|
{
|
|
|
|
|
LineHeight = 50.0f;
|
|
|
|
|
TeeSizeMod = 0.9f;
|
2014-02-02 22:23:10 +00:00
|
|
|
|
Spacing = 5.0f;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
RoundRadius = 15.0f;
|
2009-05-31 09:44:20 +00:00
|
|
|
|
}
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
2021-02-21 11:18:07 +00:00
|
|
|
|
float ScoreOffset = x + 10.0f + 10.0f, ScoreLength = TextRender()->TextWidth(0, FontSize, "00:00:00", -1, -1.0f);
|
|
|
|
|
if(IsTeamplayTeam)
|
|
|
|
|
ScoreLength = TextRender()->TextWidth(0, FontSize, "99999", -1, -1.0f);
|
2020-09-25 14:44:37 +00:00
|
|
|
|
float TeeOffset = ScoreOffset + ScoreLength + 15.0f, TeeLength = 60 * TeeSizeMod;
|
|
|
|
|
float NameOffset = TeeOffset + TeeLength, NameLength = 300.0f - TeeLength;
|
2021-02-21 11:18:07 +00:00
|
|
|
|
float CountryLength = (LineHeight - Spacing - TeeSizeMod * 5.0f) * 2.0f;
|
|
|
|
|
float PingLength = 65.0f;
|
|
|
|
|
float PingOffset = x + w - PingLength - 10.0f - 10.0f;
|
|
|
|
|
float CountryOffset = PingOffset - CountryLength;
|
|
|
|
|
float ClanLength = w - ((NameOffset - x) + NameLength) - (w - (CountryOffset - x));
|
|
|
|
|
float ClanOffset = CountryOffset - ClanLength;
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
|
|
|
|
// render headlines
|
2021-02-21 11:18:07 +00:00
|
|
|
|
x += 10.0f;
|
2011-03-19 17:28:47 +00:00
|
|
|
|
y += 50.0f;
|
|
|
|
|
float HeadlineFontsize = 22.0f;
|
2019-06-04 22:44:59 +00:00
|
|
|
|
const char *pScore = (m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard) ? Localize("Time") : Localize("Score");
|
2020-09-25 14:44:37 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, HeadlineFontsize, pScore, -1, -1.0f);
|
|
|
|
|
TextRender()->Text(0, ScoreOffset + ScoreLength - tw, y + (HeadlineFontsize * 2.f - HeadlineFontsize) / 2.f, HeadlineFontsize, pScore, -1.0f);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2020-07-15 19:42:48 +00:00
|
|
|
|
TextRender()->Text(0, NameOffset, y + (HeadlineFontsize * 2.f - HeadlineFontsize) / 2.f, HeadlineFontsize, Localize("Name"), -1.0f);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, HeadlineFontsize, Localize("Clan"), -1, -1.0f);
|
2021-02-21 11:18:07 +00:00
|
|
|
|
TextRender()->Text(0, ClanOffset + (ClanLength - tw) / 2, y + (HeadlineFontsize * 2.f - HeadlineFontsize) / 2.f, HeadlineFontsize, Localize("Clan"), -1.0f);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, HeadlineFontsize, Localize("Ping"), -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, PingOffset + PingLength - tw, y + (HeadlineFontsize * 2.f - HeadlineFontsize) / 2.f, HeadlineFontsize, Localize("Ping"), -1.0f);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
|
|
|
|
|
// render player entries
|
2020-09-25 14:44:37 +00:00
|
|
|
|
y += HeadlineFontsize * 2.0f;
|
2011-03-19 17:28:47 +00:00
|
|
|
|
CTextCursor Cursor;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2014-01-08 03:11:50 +00:00
|
|
|
|
int rendered = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(upper16)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
rendered = -16;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(upper32)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
rendered = -32;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(upper24)
|
2014-01-19 21:08:33 +00:00
|
|
|
|
rendered = -24;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
|
2014-01-22 14:38:05 +00:00
|
|
|
|
int OldDDTeam = -1;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
|
2011-01-11 22:03:01 +00:00
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// make sure that we render the correct team
|
2022-06-30 22:36:32 +00:00
|
|
|
|
const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_apInfoByDDTeamScore[i];
|
2011-01-11 22:03:01 +00:00
|
|
|
|
if(!pInfo || pInfo->m_Team != Team)
|
|
|
|
|
continue;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(rendered++ < 0)
|
|
|
|
|
continue;
|
2013-12-31 05:13:57 +00:00
|
|
|
|
|
2019-04-11 10:21:42 +00:00
|
|
|
|
int DDTeam = m_pClient->m_Teams.Team(pInfo->m_ClientID);
|
2014-01-22 00:39:18 +00:00
|
|
|
|
int NextDDTeam = 0;
|
|
|
|
|
|
|
|
|
|
for(int j = i + 1; j < MAX_CLIENTS; j++)
|
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
|
const CNetObj_PlayerInfo *pInfo2 = m_pClient->m_Snap.m_apInfoByDDTeamScore[j];
|
2014-01-22 00:39:18 +00:00
|
|
|
|
|
|
|
|
|
if(!pInfo2 || pInfo2->m_Team != Team)
|
|
|
|
|
continue;
|
|
|
|
|
|
2019-04-11 10:21:42 +00:00
|
|
|
|
NextDDTeam = m_pClient->m_Teams.Team(pInfo2->m_ClientID);
|
2014-01-22 00:39:18 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(OldDDTeam == -1)
|
2014-01-22 14:38:05 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
for(int j = i - 1; j >= 0; j--)
|
2014-01-22 14:38:05 +00:00
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
|
const CNetObj_PlayerInfo *pInfo2 = m_pClient->m_Snap.m_apInfoByDDTeamScore[j];
|
2014-01-22 14:38:05 +00:00
|
|
|
|
|
|
|
|
|
if(!pInfo2 || pInfo2->m_Team != Team)
|
|
|
|
|
continue;
|
|
|
|
|
|
2019-04-11 10:21:42 +00:00
|
|
|
|
OldDDTeam = m_pClient->m_Teams.Team(pInfo2->m_ClientID);
|
2014-01-22 14:38:05 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(DDTeam != TEAM_FLOCK)
|
2014-01-22 00:39:18 +00:00
|
|
|
|
{
|
2022-07-09 14:54:13 +00:00
|
|
|
|
ColorRGBA Color = color_cast<ColorRGBA>(ColorHSLA(DDTeam / 64.0f, 1.0f, 0.5f, 0.5f));
|
2014-01-22 00:39:18 +00:00
|
|
|
|
int Corners = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(OldDDTeam != DDTeam)
|
2014-01-22 00:39:18 +00:00
|
|
|
|
Corners |= CUI::CORNER_TL | CUI::CORNER_TR;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(NextDDTeam != DDTeam)
|
2014-01-22 00:39:18 +00:00
|
|
|
|
Corners |= CUI::CORNER_BL | CUI::CORNER_BR;
|
2022-07-09 14:54:13 +00:00
|
|
|
|
RenderTools()->DrawRect(x - 10.0f, y, w, LineHeight + Spacing, Color, Corners, RoundRadius);
|
2014-01-22 00:39:18 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(NextDDTeam != DDTeam)
|
2014-01-22 00:39:18 +00:00
|
|
|
|
{
|
2014-01-22 13:04:15 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_aTeamSize[0] > 8)
|
2014-01-22 00:39:18 +00:00
|
|
|
|
{
|
2022-02-17 22:14:09 +00:00
|
|
|
|
if(DDTeam == TEAM_SUPER)
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aBuf, Localize("Super"));
|
2022-02-17 22:14:09 +00:00
|
|
|
|
else
|
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", DDTeam);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, x - 10.0f, y + Spacing + FontSize - (FontSize / 1.5f), FontSize / 1.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
|
|
|
|
Cursor.m_LineWidth = NameLength + 3;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-02-17 22:14:09 +00:00
|
|
|
|
if(DDTeam == TEAM_SUPER)
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aBuf, Localize("Super"));
|
2022-02-17 22:14:09 +00:00
|
|
|
|
else
|
|
|
|
|
str_format(aBuf, sizeof(aBuf), Localize("Team %d"), DDTeam);
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, FontSize, aBuf, -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, ScoreOffset + w / 2.0f - tw / 2.0f, y + LineHeight, FontSize / 1.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
|
|
|
|
Cursor.m_LineWidth = NameLength + 3;
|
2014-01-22 00:39:18 +00:00
|
|
|
|
}
|
|
|
|
|
TextRender()->TextEx(&Cursor, aBuf, -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OldDDTeam = DDTeam;
|
|
|
|
|
|
2011-04-05 17:00:00 +00:00
|
|
|
|
// background so it's easy to find the local player or the followed one in spectator mode
|
2022-03-14 12:25:47 +00:00
|
|
|
|
if((!m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_Local) || (m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW && pInfo->m_Local) || (m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientID == m_pClient->m_Snap.m_SpecInfo.m_SpectatorID))
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2022-07-09 14:54:13 +00:00
|
|
|
|
RenderTools()->DrawRect(x, y, w - 20.0f, LineHeight, ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, RoundRadius);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
2010-09-13 04:30:05 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// score
|
2019-06-04 22:44:59 +00:00
|
|
|
|
if(m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard)
|
2011-12-26 11:45:41 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(pInfo->m_Score == -9999)
|
2014-01-12 15:16:09 +00:00
|
|
|
|
aBuf[0] = 0;
|
|
|
|
|
else
|
2021-06-23 05:05:49 +00:00
|
|
|
|
str_time((int64_t)abs(pInfo->m_Score) * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
2011-12-26 11:45:41 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2018-10-11 20:19:26 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 99999));
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(0, FontSize, aBuf, -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, ScoreOffset + ScoreLength - tw, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
TextRender()->TextEx(&Cursor, aBuf, -1);
|
|
|
|
|
|
|
|
|
|
// flag
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS &&
|
|
|
|
|
m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID))
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2009-10-27 14:38:53 +00:00
|
|
|
|
Graphics()->BlendNormal();
|
2020-10-09 07:07:05 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID)
|
|
|
|
|
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
|
|
|
|
|
else
|
|
|
|
|
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2020-10-09 07:07:05 +00:00
|
|
|
|
Graphics()->QuadsBegin();
|
|
|
|
|
Graphics()->QuadsSetSubset(1, 0, 0, 1);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
float Size = LineHeight;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
IGraphics::CQuadItem QuadItem(TeeOffset + 0.0f, y - 5.0f - Spacing / 2.0f, Size / 2.0f, Size);
|
2010-05-29 07:25:38 +00:00
|
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
2009-10-27 14:38:53 +00:00
|
|
|
|
Graphics()->QuadsEnd();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// avatar
|
2011-02-12 10:40:36 +00:00
|
|
|
|
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
TeeInfo.m_Size *= TeeSizeMod;
|
2021-03-12 20:23:29 +00:00
|
|
|
|
CAnimState *pIdleState = CAnimState::GetIdle();
|
|
|
|
|
vec2 OffsetToMid;
|
|
|
|
|
RenderTools()->GetRenderTeeOffsetToRenderedTee(pIdleState, &TeeInfo, OffsetToMid);
|
|
|
|
|
vec2 TeeRenderPos(TeeOffset + TeeLength / 2, y + LineHeight / 2.0f + OffsetToMid.y);
|
|
|
|
|
|
|
|
|
|
RenderTools()->RenderTee(pIdleState, &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), TeeRenderPos);
|
2011-01-06 04:45:53 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// name
|
2022-05-31 10:20:45 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, NameOffset, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
2019-03-05 08:48:06 +00:00
|
|
|
|
if(m_pClient->m_aClients[pInfo->m_ClientID].m_AuthLevel)
|
2019-03-19 14:37:17 +00:00
|
|
|
|
{
|
2019-04-26 12:06:32 +00:00
|
|
|
|
ColorRGBA Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClAuthedPlayerColor));
|
2019-04-26 22:34:20 +00:00
|
|
|
|
TextRender()->TextColor(Color);
|
2019-03-19 14:37:17 +00:00
|
|
|
|
}
|
2019-03-02 10:50:33 +00:00
|
|
|
|
|
2014-08-23 09:32:54 +00:00
|
|
|
|
if(g_Config.m_ClShowIDs)
|
2011-04-09 06:41:31 +00:00
|
|
|
|
{
|
|
|
|
|
char aId[64] = "";
|
2020-12-27 00:19:36 +00:00
|
|
|
|
if(pInfo->m_ClientID < 10)
|
|
|
|
|
{
|
|
|
|
|
str_format(aId, sizeof(aId), " %d: %s", pInfo->m_ClientID, m_pClient->m_aClients[pInfo->m_ClientID].m_aName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
str_format(aId, sizeof(aId), "%d: %s", pInfo->m_ClientID, m_pClient->m_aClients[pInfo->m_ClientID].m_aName);
|
|
|
|
|
}
|
2020-09-25 14:44:37 +00:00
|
|
|
|
Cursor.m_LineWidth = NameLength;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
TextRender()->TextEx(&Cursor, aId, -1);
|
|
|
|
|
}
|
2011-01-06 04:45:53 +00:00
|
|
|
|
else
|
2011-04-09 06:41:31 +00:00
|
|
|
|
{
|
|
|
|
|
Cursor.m_LineWidth = NameLength;
|
|
|
|
|
TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1);
|
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// clan
|
2019-04-05 10:41:01 +00:00
|
|
|
|
if(str_comp(m_pClient->m_aClients[pInfo->m_ClientID].m_aClan,
|
2022-06-30 22:36:32 +00:00
|
|
|
|
m_pClient->m_aClients[GameClient()->m_aLocalIDs[g_Config.m_ClDummy]].m_aClan) == 0)
|
2019-04-05 10:41:01 +00:00
|
|
|
|
{
|
2019-04-26 12:06:32 +00:00
|
|
|
|
ColorRGBA Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClSameClanColor));
|
2019-04-26 22:34:20 +00:00
|
|
|
|
TextRender()->TextColor(Color);
|
2019-04-05 10:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
2021-02-21 11:18:07 +00:00
|
|
|
|
tw = minimum(TextRender()->TextWidth(nullptr, FontSize, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1, -1.0f), ClanLength);
|
2022-05-31 10:20:45 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - tw) / 2, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
Cursor.m_LineWidth = ClanLength;
|
|
|
|
|
TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);
|
|
|
|
|
|
2019-04-05 10:41:01 +00:00
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// country flag
|
2019-04-26 21:47:34 +00:00
|
|
|
|
ColorRGBA Color(1.0f, 1.0f, 1.0f, 0.5f);
|
2021-07-12 09:43:56 +00:00
|
|
|
|
m_pClient->m_CountryFlags.Render(m_pClient->m_aClients[pInfo->m_ClientID].m_Country, &Color,
|
2020-09-26 19:41:58 +00:00
|
|
|
|
CountryOffset, y + (Spacing + TeeSizeMod * 5.0f) / 2.0f, CountryLength, LineHeight - Spacing - TeeSizeMod * 5.0f);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-03-19 17:28:47 +00:00
|
|
|
|
// ping
|
2019-04-05 11:25:17 +00:00
|
|
|
|
if(g_Config.m_ClEnablePingColor)
|
|
|
|
|
{
|
2019-04-26 12:06:32 +00:00
|
|
|
|
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA((300.0f - clamp(pInfo->m_Latency, 0, 300)) / 1000.0f, 1.0f, 0.5f));
|
2019-04-26 22:34:20 +00:00
|
|
|
|
TextRender()->TextColor(rgb);
|
2019-04-05 11:12:08 +00:00
|
|
|
|
}
|
2019-10-13 15:17:05 +00:00
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 999));
|
2020-07-15 19:10:13 +00:00
|
|
|
|
tw = TextRender()->TextWidth(nullptr, FontSize, aBuf, -1, -1.0f);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->SetCursor(&Cursor, PingOffset + PingLength - tw, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
2011-03-19 17:28:47 +00:00
|
|
|
|
Cursor.m_LineWidth = PingLength;
|
|
|
|
|
TextRender()->TextEx(&Cursor, aBuf, -1);
|
|
|
|
|
|
2019-04-05 11:12:08 +00:00
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
y += LineHeight + Spacing;
|
|
|
|
|
if(lower32 || upper32)
|
|
|
|
|
{
|
|
|
|
|
if(rendered == 32)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if(lower24 || upper24)
|
|
|
|
|
{
|
|
|
|
|
if(rendered == 24)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(rendered == 16)
|
|
|
|
|
break;
|
2014-01-08 03:11:50 +00:00
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-07 17:03:59 +00:00
|
|
|
|
void CScoreboard::RenderRecordingNotification(float x)
|
|
|
|
|
{
|
2015-07-09 00:00:40 +00:00
|
|
|
|
if(!m_pClient->DemoRecorder(RECORDER_MANUAL)->IsRecording() &&
|
2020-09-26 19:41:58 +00:00
|
|
|
|
!m_pClient->DemoRecorder(RECORDER_AUTO)->IsRecording() &&
|
|
|
|
|
!m_pClient->DemoRecorder(RECORDER_RACE)->IsRecording() &&
|
|
|
|
|
!m_pClient->DemoRecorder(RECORDER_REPLAYS)->IsRecording())
|
2015-07-09 00:00:40 +00:00
|
|
|
|
{
|
2010-09-07 17:03:59 +00:00
|
|
|
|
return;
|
2015-07-09 00:00:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//draw the text
|
|
|
|
|
char aBuf[64] = "\0";
|
|
|
|
|
char aBuf2[64];
|
2020-10-18 21:33:45 +00:00
|
|
|
|
char aTime[32];
|
2015-07-09 00:00:40 +00:00
|
|
|
|
|
|
|
|
|
if(m_pClient->DemoRecorder(RECORDER_MANUAL)->IsRecording())
|
|
|
|
|
{
|
2021-06-23 05:05:49 +00:00
|
|
|
|
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_MANUAL)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
2020-10-18 21:33:45 +00:00
|
|
|
|
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Manual"), aTime);
|
2015-07-09 00:00:40 +00:00
|
|
|
|
str_append(aBuf, aBuf2, sizeof(aBuf));
|
|
|
|
|
}
|
|
|
|
|
if(m_pClient->DemoRecorder(RECORDER_RACE)->IsRecording())
|
|
|
|
|
{
|
2021-06-23 05:05:49 +00:00
|
|
|
|
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_RACE)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
2020-10-18 21:33:45 +00:00
|
|
|
|
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Race"), aTime);
|
2015-07-09 00:00:40 +00:00
|
|
|
|
str_append(aBuf, aBuf2, sizeof(aBuf));
|
|
|
|
|
}
|
|
|
|
|
if(m_pClient->DemoRecorder(RECORDER_AUTO)->IsRecording())
|
|
|
|
|
{
|
2021-06-23 05:05:49 +00:00
|
|
|
|
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_AUTO)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
2020-10-18 21:33:45 +00:00
|
|
|
|
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Auto"), aTime);
|
2015-07-09 00:00:40 +00:00
|
|
|
|
str_append(aBuf, aBuf2, sizeof(aBuf));
|
|
|
|
|
}
|
2019-06-05 17:49:00 +00:00
|
|
|
|
if(m_pClient->DemoRecorder(RECORDER_REPLAYS)->IsRecording())
|
2019-05-21 10:49:19 +00:00
|
|
|
|
{
|
2021-06-23 05:05:49 +00:00
|
|
|
|
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_REPLAYS)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
2020-10-18 21:33:45 +00:00
|
|
|
|
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Replay"), aTime);
|
2019-05-21 10:49:19 +00:00
|
|
|
|
str_append(aBuf, aBuf2, sizeof(aBuf));
|
|
|
|
|
}
|
2015-07-09 00:00:40 +00:00
|
|
|
|
|
2020-07-15 19:10:13 +00:00
|
|
|
|
float w = TextRender()->TextWidth(0, 20.0f, aBuf, -1, -1.0f);
|
2010-09-07 17:03:59 +00:00
|
|
|
|
|
2022-07-09 14:54:13 +00:00
|
|
|
|
// draw the box
|
|
|
|
|
RenderTools()->DrawRect(x, 0.0f, w + 60.0f, 50.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.4f), CUI::CORNER_B, 15.0f);
|
|
|
|
|
|
|
|
|
|
// draw the red dot
|
|
|
|
|
RenderTools()->DrawRect(x + 20, 15.0f, 20.0f, 20.0f, ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f), CUI::CORNER_ALL, 10.0f);
|
2010-09-07 17:03:59 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
TextRender()->Text(0, x + 50.0f, (50.f - 20.f) / 2.f, 20.0f, aBuf, -1.0f);
|
2010-09-07 17:03:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
void CScoreboard::OnRender()
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-01-17 12:42:40 +00:00
|
|
|
|
if(!Active())
|
2008-08-31 21:50:14 +00:00
|
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2018-02-04 15:00:47 +00:00
|
|
|
|
// if the score board is active, then we should clear the motd message as well
|
2021-07-12 09:43:56 +00:00
|
|
|
|
if(m_pClient->m_Motd.IsActive())
|
|
|
|
|
m_pClient->m_Motd.Clear();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
float Width = 400 * 3.0f * Graphics()->ScreenAspect();
|
|
|
|
|
float Height = 400 * 3.0f;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
|
Graphics()->MapScreen(0, 0, Width, Height);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2021-02-21 11:18:07 +00:00
|
|
|
|
float w = 750.0f;
|
|
|
|
|
float ExtraWidthSingle = 20.0f;
|
2010-09-27 19:41:41 +00:00
|
|
|
|
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj)
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS))
|
2013-12-31 05:13:57 +00:00
|
|
|
|
{
|
2014-01-19 21:08:33 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_aTeamSize[0] > 48)
|
2014-01-08 03:11:50 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
RenderScoreboard(Width / 2, 150.0f, w, -5, "");
|
2020-12-31 09:03:15 +00:00
|
|
|
|
RenderScoreboard(Width / 2 - w, 150.0f, w, -4, 0);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
else if(m_pClient->m_Snap.m_aTeamSize[0] > 32)
|
2014-01-19 21:08:33 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
RenderScoreboard(Width / 2, 150.0f, w, -8, "");
|
2020-12-31 09:03:15 +00:00
|
|
|
|
RenderScoreboard(Width / 2 - w, 150.0f, w, -7, 0);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
else if(m_pClient->m_Snap.m_aTeamSize[0] > 16)
|
2013-12-31 05:13:57 +00:00
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
|
RenderScoreboard(Width / 2, 150.0f, w, -3, "");
|
2020-12-31 09:03:15 +00:00
|
|
|
|
RenderScoreboard(Width / 2 - w, 150.0f, w, -6, 0);
|
2020-09-26 19:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2013-12-31 05:13:57 +00:00
|
|
|
|
{
|
2021-02-21 11:18:07 +00:00
|
|
|
|
w += ExtraWidthSingle;
|
|
|
|
|
RenderScoreboard(Width / 2 - w / 2, 150.0f, w, -2, 0);
|
2013-12-31 05:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2011-03-04 16:08:10 +00:00
|
|
|
|
else
|
2008-08-27 15:48:50 +00:00
|
|
|
|
{
|
2011-04-02 14:24:08 +00:00
|
|
|
|
const char *pRedClanName = GetClanName(TEAM_RED);
|
|
|
|
|
const char *pBlueClanName = GetClanName(TEAM_BLUE);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER && m_pClient->m_Snap.m_pGameDataObj)
|
2011-03-04 16:08:10 +00:00
|
|
|
|
{
|
2011-04-02 14:24:08 +00:00
|
|
|
|
char aText[256];
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aText, Localize("Draw!"));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-03-04 16:08:10 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue)
|
2011-04-02 14:24:08 +00:00
|
|
|
|
{
|
|
|
|
|
if(pRedClanName)
|
|
|
|
|
str_format(aText, sizeof(aText), Localize("%s wins!"), pRedClanName);
|
|
|
|
|
else
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aText, Localize("Red team wins!"));
|
2011-04-02 14:24:08 +00:00
|
|
|
|
}
|
2011-03-04 16:08:10 +00:00
|
|
|
|
else if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed)
|
2011-04-02 14:24:08 +00:00
|
|
|
|
{
|
|
|
|
|
if(pBlueClanName)
|
|
|
|
|
str_format(aText, sizeof(aText), Localize("%s wins!"), pBlueClanName);
|
|
|
|
|
else
|
2022-07-09 16:14:56 +00:00
|
|
|
|
str_copy(aText, Localize("Blue team wins!"));
|
2011-04-02 14:24:08 +00:00
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2022-03-20 11:57:50 +00:00
|
|
|
|
float TextWidth = TextRender()->TextWidth(0, 86.0f, aText, -1, -1.0f);
|
|
|
|
|
TextRender()->Text(0, Width / 2 - TextWidth / 2, 39, 86.0f, aText, -1.0f);
|
2011-03-04 16:08:10 +00:00
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2021-02-21 11:18:07 +00:00
|
|
|
|
//decrease width, because team games use additional offsets
|
|
|
|
|
w -= 10.0f;
|
|
|
|
|
|
2020-11-05 11:15:27 +00:00
|
|
|
|
int NumPlayers = maximum(m_pClient->m_Snap.m_aTeamSize[TEAM_RED], m_pClient->m_Snap.m_aTeamSize[TEAM_BLUE]);
|
|
|
|
|
RenderScoreboard(Width / 2 - w - 5.0f, 150.0f, w, TEAM_RED, pRedClanName ? pRedClanName : Localize("Red team"), NumPlayers);
|
|
|
|
|
RenderScoreboard(Width / 2 + 5.0f, 150.0f, w, TEAM_BLUE, pBlueClanName ? pBlueClanName : Localize("Blue team"), NumPlayers);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-16 13:30:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj && (m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit || m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit || (m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum && m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent)))
|
|
|
|
|
{
|
|
|
|
|
RenderGoals(Width / 2 - w / 2, 150 + 760 + 10, w);
|
|
|
|
|
RenderSpectators(Width / 2 - w / 2, 150 + 760 + 10 + 50 + 10, w, 160.0f);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
RenderSpectators(Width / 2 - w / 2, 150 + 760 + 10, w, 200.0f);
|
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
2022-04-01 19:48:06 +00:00
|
|
|
|
RenderRecordingNotification((Width / 7) * 4 + 20);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
}
|
2010-08-18 01:57:35 +00:00
|
|
|
|
|
|
|
|
|
bool CScoreboard::Active()
|
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
|
// if statboard is active don't show scoreboard
|
2021-07-12 09:43:56 +00:00
|
|
|
|
if(m_pClient->m_Statboard.IsActive())
|
2015-05-21 09:55:51 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2011-01-17 12:42:40 +00:00
|
|
|
|
if(m_Active)
|
|
|
|
|
return true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2022-03-14 12:25:47 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pLocalInfo && !m_pClient->m_Snap.m_SpecInfo.m_Active)
|
2011-01-17 12:42:40 +00:00
|
|
|
|
{
|
|
|
|
|
// we are not a spectator, check if we are dead
|
2015-08-12 09:30:26 +00:00
|
|
|
|
if(!m_pClient->m_Snap.m_pLocalCharacter && g_Config.m_ClScoreboardOnDeath)
|
2011-01-17 12:42:40 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the game is over
|
2020-09-26 19:41:58 +00:00
|
|
|
|
if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER)
|
2011-01-17 12:42:40 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
2010-08-18 01:57:35 +00:00
|
|
|
|
}
|
2011-04-02 14:24:08 +00:00
|
|
|
|
|
|
|
|
|
const char *CScoreboard::GetClanName(int Team)
|
|
|
|
|
{
|
|
|
|
|
int ClanPlayers = 0;
|
|
|
|
|
const char *pClanName = 0;
|
2022-06-30 22:36:32 +00:00
|
|
|
|
for(const auto *pInfo : m_pClient->m_Snap.m_apInfoByScore)
|
2011-04-02 14:24:08 +00:00
|
|
|
|
{
|
|
|
|
|
if(!pInfo || pInfo->m_Team != Team)
|
|
|
|
|
continue;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-04-02 14:24:08 +00:00
|
|
|
|
if(!pClanName)
|
|
|
|
|
{
|
|
|
|
|
pClanName = m_pClient->m_aClients[pInfo->m_ClientID].m_aClan;
|
|
|
|
|
ClanPlayers++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(str_comp(m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, pClanName) == 0)
|
|
|
|
|
ClanPlayers++;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
|
2011-04-02 14:24:08 +00:00
|
|
|
|
if(ClanPlayers > 1 && pClanName[0])
|
|
|
|
|
return pClanName;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|