mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge pull request #7958 from Robyt3/Infomessages-Refactoring
Refactor `CInfoMessages`
This commit is contained in:
commit
62afe9ee89
|
@ -14,11 +14,14 @@
|
|||
#include <game/client/prediction/entities/character.h>
|
||||
#include <game/client/prediction/gameworld.h>
|
||||
|
||||
static constexpr float ROW_HEIGHT = 46.0f;
|
||||
static constexpr float FONT_SIZE = 36.0f;
|
||||
|
||||
void CInfoMessages::OnWindowResize()
|
||||
{
|
||||
for(auto &InfoMsg : m_aInfoMsgs)
|
||||
{
|
||||
DeleteTextContainers(&InfoMsg);
|
||||
DeleteTextContainers(InfoMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,16 +31,16 @@ void CInfoMessages::OnReset()
|
|||
for(auto &InfoMsg : m_aInfoMsgs)
|
||||
{
|
||||
InfoMsg.m_Tick = -100000;
|
||||
DeleteTextContainers(&InfoMsg);
|
||||
DeleteTextContainers(InfoMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoMessages::DeleteTextContainers(CInfoMsg *pInfoMsg)
|
||||
void CInfoMessages::DeleteTextContainers(CInfoMsg &InfoMsg)
|
||||
{
|
||||
TextRender()->DeleteTextContainer(pInfoMsg->m_VictimTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(pInfoMsg->m_KillerTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(pInfoMsg->m_DiffTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(pInfoMsg->m_TimeTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(InfoMsg.m_VictimTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(InfoMsg.m_KillerTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(InfoMsg.m_DiffTextContainerIndex);
|
||||
TextRender()->DeleteTextContainer(InfoMsg.m_TimeTextContainerIndex);
|
||||
}
|
||||
|
||||
void CInfoMessages::OnInit()
|
||||
|
@ -65,87 +68,119 @@ void CInfoMessages::OnInit()
|
|||
Graphics()->QuadContainerUpload(m_SpriteQuadContainerIndex);
|
||||
}
|
||||
|
||||
void CInfoMessages::AddInfoMsg(EType Type, CInfoMsg NewMsg)
|
||||
CInfoMessages::CInfoMsg CInfoMessages::CreateInfoMsg(EType Type)
|
||||
{
|
||||
NewMsg.m_Type = Type;
|
||||
NewMsg.m_Tick = Client()->GameTick(g_Config.m_ClDummy);
|
||||
CInfoMsg InfoMsg;
|
||||
InfoMsg.m_Type = Type;
|
||||
InfoMsg.m_Tick = Client()->GameTick(g_Config.m_ClDummy);
|
||||
|
||||
for(int i = 0; i < MAX_KILLMSG_TEAM_MEMBERS; i++)
|
||||
{
|
||||
InfoMsg.m_aVictimIds[i] = -1;
|
||||
InfoMsg.m_aVictimRenderInfo[i].Reset();
|
||||
}
|
||||
InfoMsg.m_VictimDDTeam = 0;
|
||||
InfoMsg.m_aVictimName[0] = '\0';
|
||||
InfoMsg.m_VictimTextContainerIndex.Reset();
|
||||
|
||||
InfoMsg.m_KillerID = -1;
|
||||
InfoMsg.m_aKillerName[0] = '\0';
|
||||
InfoMsg.m_KillerTextContainerIndex.Reset();
|
||||
InfoMsg.m_KillerRenderInfo.Reset();
|
||||
|
||||
InfoMsg.m_Weapon = -1;
|
||||
InfoMsg.m_ModeSpecial = 0;
|
||||
InfoMsg.m_FlagCarrierBlue = -1;
|
||||
InfoMsg.m_TeamSize = 0;
|
||||
|
||||
InfoMsg.m_Diff = 0;
|
||||
InfoMsg.m_aTimeText[0] = '\0';
|
||||
InfoMsg.m_aDiffText[0] = '\0';
|
||||
InfoMsg.m_TimeTextContainerIndex.Reset();
|
||||
InfoMsg.m_DiffTextContainerIndex.Reset();
|
||||
InfoMsg.m_RecordPersonal = false;
|
||||
return InfoMsg;
|
||||
}
|
||||
|
||||
void CInfoMessages::AddInfoMsg(const CInfoMsg &InfoMsg)
|
||||
{
|
||||
if(InfoMsg.m_KillerID >= 0 && !InfoMsg.m_KillerRenderInfo.Valid())
|
||||
return;
|
||||
for(int i = 0; i < InfoMsg.m_TeamSize; i++)
|
||||
{
|
||||
if(InfoMsg.m_aVictimIds[i] < 0 || !InfoMsg.m_aVictimRenderInfo[i].Valid())
|
||||
return;
|
||||
}
|
||||
|
||||
const float Height = 1.5f * 400.0f * 3.0f;
|
||||
const float Width = Height * Graphics()->ScreenAspect();
|
||||
|
||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||
Graphics()->MapScreen(0, 0, Width, Height);
|
||||
|
||||
m_InfoMsgCurrent = (m_InfoMsgCurrent + 1) % MAX_INFOMSGS;
|
||||
DeleteTextContainers(&m_aInfoMsgs[m_InfoMsgCurrent]);
|
||||
m_aInfoMsgs[m_InfoMsgCurrent] = NewMsg;
|
||||
DeleteTextContainers(m_aInfoMsgs[m_InfoMsgCurrent]);
|
||||
m_aInfoMsgs[m_InfoMsgCurrent] = InfoMsg;
|
||||
CreateTextContainersIfNotCreated(m_aInfoMsgs[m_InfoMsgCurrent]);
|
||||
|
||||
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
}
|
||||
|
||||
void CInfoMessages::CreateNamesIfNotCreated(CInfoMsg *pInfoMsg)
|
||||
void CInfoMessages::CreateTextContainersIfNotCreated(CInfoMsg &InfoMsg)
|
||||
{
|
||||
const float FontSize = 36.0f;
|
||||
if(!pInfoMsg->m_VictimTextContainerIndex.Valid() && pInfoMsg->m_aVictimName[0] != 0)
|
||||
{
|
||||
pInfoMsg->m_VictimTextWidth = TextRender()->TextWidth(FontSize, pInfoMsg->m_aVictimName);
|
||||
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_RENDER);
|
||||
Cursor.m_LineWidth = -1;
|
||||
|
||||
unsigned Color = g_Config.m_ClKillMessageNormalColor;
|
||||
if(pInfoMsg->m_aVictimIds[0] == m_pClient->m_Snap.m_LocalClientID)
|
||||
const auto &&NameColor = [&](int ClientID) -> ColorRGBA {
|
||||
unsigned Color;
|
||||
if(ClientID == m_pClient->m_Snap.m_LocalClientID)
|
||||
{
|
||||
Color = g_Config.m_ClKillMessageHighlightColor;
|
||||
}
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(Color)));
|
||||
|
||||
TextRender()->CreateTextContainer(pInfoMsg->m_VictimTextContainerIndex, &Cursor, pInfoMsg->m_aVictimName);
|
||||
}
|
||||
|
||||
if(!pInfoMsg->m_KillerTextContainerIndex.Valid() && pInfoMsg->m_aKillerName[0] != 0)
|
||||
{
|
||||
pInfoMsg->m_KillerTextWidth = TextRender()->TextWidth(FontSize, pInfoMsg->m_aKillerName);
|
||||
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_RENDER);
|
||||
Cursor.m_LineWidth = -1;
|
||||
|
||||
unsigned Color = g_Config.m_ClKillMessageNormalColor;
|
||||
if(pInfoMsg->m_KillerID == m_pClient->m_Snap.m_LocalClientID)
|
||||
else
|
||||
{
|
||||
Color = g_Config.m_ClKillMessageHighlightColor;
|
||||
Color = g_Config.m_ClKillMessageNormalColor;
|
||||
}
|
||||
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(Color)));
|
||||
return color_cast<ColorRGBA>(ColorHSLA(Color));
|
||||
};
|
||||
|
||||
TextRender()->CreateTextContainer(pInfoMsg->m_KillerTextContainerIndex, &Cursor, pInfoMsg->m_aKillerName);
|
||||
}
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
|
||||
void CInfoMessages::CreateFinishTextContainersIfNotCreated(CInfoMsg *pInfoMsg)
|
||||
{
|
||||
const float FontSize = 36.0f;
|
||||
if(!pInfoMsg->m_DiffTextContainerIndex.Valid() && pInfoMsg->m_aDiffText[0] != 0)
|
||||
if(!InfoMsg.m_VictimTextContainerIndex.Valid() && InfoMsg.m_aVictimName[0] != '\0')
|
||||
{
|
||||
pInfoMsg->m_DiffTextWidth = TextRender()->TextWidth(FontSize, pInfoMsg->m_aDiffText);
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_RENDER);
|
||||
Cursor.m_LineWidth = -1;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FONT_SIZE, TEXTFLAG_RENDER);
|
||||
TextRender()->TextColor(NameColor(InfoMsg.m_aVictimIds[0]));
|
||||
TextRender()->CreateTextContainer(InfoMsg.m_VictimTextContainerIndex, &Cursor, InfoMsg.m_aVictimName);
|
||||
}
|
||||
|
||||
if(pInfoMsg->m_Diff > 0)
|
||||
TextRender()->TextColor(1.0f, 0.5f, 0.5f, 1); // red
|
||||
else if(pInfoMsg->m_Diff < 0)
|
||||
TextRender()->TextColor(0.5f, 1.0f, 0.5f, 1); // green
|
||||
if(!InfoMsg.m_KillerTextContainerIndex.Valid() && InfoMsg.m_aKillerName[0] != '\0')
|
||||
{
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FONT_SIZE, TEXTFLAG_RENDER);
|
||||
TextRender()->TextColor(NameColor(InfoMsg.m_KillerID));
|
||||
TextRender()->CreateTextContainer(InfoMsg.m_KillerTextContainerIndex, &Cursor, InfoMsg.m_aKillerName);
|
||||
}
|
||||
|
||||
if(!InfoMsg.m_DiffTextContainerIndex.Valid() && InfoMsg.m_aDiffText[0] != '\0')
|
||||
{
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FONT_SIZE, TEXTFLAG_RENDER);
|
||||
|
||||
if(InfoMsg.m_Diff > 0)
|
||||
TextRender()->TextColor(1.0f, 0.5f, 0.5f, 1.0f); // red
|
||||
else if(InfoMsg.m_Diff < 0)
|
||||
TextRender()->TextColor(0.5f, 1.0f, 0.5f, 1.0f); // green
|
||||
else
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
|
||||
TextRender()->CreateTextContainer(pInfoMsg->m_DiffTextContainerIndex, &Cursor, pInfoMsg->m_aDiffText);
|
||||
TextRender()->CreateTextContainer(InfoMsg.m_DiffTextContainerIndex, &Cursor, InfoMsg.m_aDiffText);
|
||||
}
|
||||
if(!pInfoMsg->m_TimeTextContainerIndex.Valid() && pInfoMsg->m_aTimeText[0] != 0)
|
||||
|
||||
if(!InfoMsg.m_TimeTextContainerIndex.Valid() && InfoMsg.m_aTimeText[0] != '\0')
|
||||
{
|
||||
pInfoMsg->m_TimeTextWidth = TextRender()->TextWidth(FontSize, pInfoMsg->m_aTimeText);
|
||||
CTextCursor Cursor;
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_RENDER);
|
||||
Cursor.m_LineWidth = -1;
|
||||
|
||||
TextRender()->SetCursor(&Cursor, 0, 0, FONT_SIZE, TEXTFLAG_RENDER);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
|
||||
TextRender()->CreateTextContainer(pInfoMsg->m_TimeTextContainerIndex, &Cursor, pInfoMsg->m_aTimeText);
|
||||
TextRender()->CreateTextContainer(InfoMsg.m_TimeTextContainerIndex, &Cursor, InfoMsg.m_aTimeText);
|
||||
}
|
||||
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
|
||||
|
@ -154,384 +189,264 @@ void CInfoMessages::OnMessage(int MsgType, void *pRawMsg)
|
|||
if(m_pClient->m_SuppressEvents)
|
||||
return;
|
||||
|
||||
if(MsgType == NETMSGTYPE_SV_KILLMSGTEAM)
|
||||
switch(MsgType)
|
||||
{
|
||||
CNetMsg_Sv_KillMsgTeam *pMsg = (CNetMsg_Sv_KillMsgTeam *)pRawMsg;
|
||||
|
||||
CInfoMsg Kill{};
|
||||
|
||||
std::vector<std::pair<int, int>> vStrongWeakSorted;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_pClient->m_Teams.Team(i) == pMsg->m_Team)
|
||||
{
|
||||
CCharacter *pChr = m_pClient->m_GameWorld.GetCharacterByID(i);
|
||||
vStrongWeakSorted.emplace_back(i, pMsg->m_First == i ? MAX_CLIENTS : pChr ? pChr->GetStrongWeakID() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::stable_sort(vStrongWeakSorted.begin(), vStrongWeakSorted.end(), [](auto &Left, auto &Right) { return Left.second > Right.second; });
|
||||
|
||||
Kill.m_TeamSize = vStrongWeakSorted.size();
|
||||
if(Kill.m_TeamSize > MAX_KILLMSG_TEAM_MEMBERS)
|
||||
Kill.m_TeamSize = MAX_KILLMSG_TEAM_MEMBERS;
|
||||
|
||||
Kill.m_VictimDDTeam = pMsg->m_Team;
|
||||
for(int i = 0; i < Kill.m_TeamSize; i++)
|
||||
{
|
||||
if(m_pClient->m_aClients[vStrongWeakSorted[i].first].m_Active)
|
||||
{
|
||||
Kill.m_aVictimIds[i] = vStrongWeakSorted[i].first;
|
||||
Kill.m_aVictimRenderInfo[i] = m_pClient->m_aClients[vStrongWeakSorted[i].first].m_RenderInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
Kill.m_aVictimIds[i] = -1;
|
||||
Kill.m_aVictimRenderInfo[i].Reset();
|
||||
}
|
||||
}
|
||||
for(int i = Kill.m_TeamSize; i < MAX_KILLMSG_TEAM_MEMBERS; i++)
|
||||
{
|
||||
Kill.m_aVictimIds[i] = -1;
|
||||
Kill.m_aVictimRenderInfo[i].Reset();
|
||||
}
|
||||
str_format(Kill.m_aVictimName, sizeof(Kill.m_aVictimName), Localize("Team %d"), pMsg->m_Team);
|
||||
|
||||
Kill.m_KillerID = -1;
|
||||
Kill.m_aKillerName[0] = '\0';
|
||||
Kill.m_KillerRenderInfo.Reset();
|
||||
|
||||
Kill.m_Weapon = -1;
|
||||
Kill.m_ModeSpecial = 0;
|
||||
|
||||
Kill.m_VictimTextWidth = Kill.m_KillerTextWidth = 0.f;
|
||||
|
||||
float Height = 400 * 3.0f;
|
||||
float Width = Height * Graphics()->ScreenAspect();
|
||||
|
||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||
Graphics()->MapScreen(0, 0, Width * 1.5f, Height * 1.5f);
|
||||
|
||||
CreateNamesIfNotCreated(&Kill);
|
||||
|
||||
bool KillMsgValid = true;
|
||||
for(int i = 0; i < Kill.m_TeamSize; i++)
|
||||
{
|
||||
KillMsgValid = KillMsgValid && Kill.m_aVictimIds[i] >= 0 && ((Kill.m_aVictimRenderInfo[i].m_CustomColoredSkin && Kill.m_aVictimRenderInfo[i].m_ColorableRenderSkin.m_Body.IsValid()) || (!Kill.m_aVictimRenderInfo[i].m_CustomColoredSkin && Kill.m_aVictimRenderInfo[i].m_OriginalRenderSkin.m_Body.IsValid()));
|
||||
}
|
||||
|
||||
if(KillMsgValid)
|
||||
{
|
||||
AddInfoMsg(EType::TYPE_KILL, Kill);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteTextContainers(&Kill);
|
||||
}
|
||||
|
||||
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
}
|
||||
|
||||
if(MsgType == NETMSGTYPE_SV_KILLMSG)
|
||||
{
|
||||
CNetMsg_Sv_KillMsg *pMsg = (CNetMsg_Sv_KillMsg *)pRawMsg;
|
||||
|
||||
CInfoMsg Kill{};
|
||||
|
||||
Kill.m_TeamSize = 1;
|
||||
Kill.m_aVictimIds[0] = pMsg->m_Victim;
|
||||
if(Kill.m_aVictimIds[0] >= 0 && Kill.m_aVictimIds[0] < MAX_CLIENTS)
|
||||
{
|
||||
Kill.m_VictimDDTeam = m_pClient->m_Teams.Team(Kill.m_aVictimIds[0]);
|
||||
str_copy(Kill.m_aVictimName, m_pClient->m_aClients[Kill.m_aVictimIds[0]].m_aName);
|
||||
Kill.m_aVictimRenderInfo[0] = m_pClient->m_aClients[Kill.m_aVictimIds[0]].m_RenderInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
Kill.m_VictimDDTeam = 0;
|
||||
Kill.m_aVictimName[0] = '\0';
|
||||
}
|
||||
for(int i = Kill.m_TeamSize; i < MAX_KILLMSG_TEAM_MEMBERS; i++)
|
||||
{
|
||||
Kill.m_aVictimIds[i] = -1;
|
||||
Kill.m_aVictimRenderInfo[i].Reset();
|
||||
}
|
||||
|
||||
Kill.m_KillerID = pMsg->m_Killer;
|
||||
if(Kill.m_KillerID >= 0 && Kill.m_KillerID < MAX_CLIENTS)
|
||||
{
|
||||
str_copy(Kill.m_aKillerName, m_pClient->m_aClients[Kill.m_KillerID].m_aName);
|
||||
Kill.m_KillerRenderInfo = m_pClient->m_aClients[Kill.m_KillerID].m_RenderInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
Kill.m_aKillerName[0] = '\0';
|
||||
Kill.m_KillerRenderInfo.Reset();
|
||||
}
|
||||
|
||||
Kill.m_Weapon = pMsg->m_Weapon;
|
||||
Kill.m_ModeSpecial = pMsg->m_ModeSpecial;
|
||||
|
||||
Kill.m_FlagCarrierBlue = m_pClient->m_Snap.m_pGameDataObj ? m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue : -1;
|
||||
|
||||
Kill.m_VictimTextWidth = Kill.m_KillerTextWidth = 0.f;
|
||||
|
||||
float Height = 400 * 3.0f;
|
||||
float Width = Height * Graphics()->ScreenAspect();
|
||||
|
||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||
Graphics()->MapScreen(0, 0, Width * 1.5f, Height * 1.5f);
|
||||
|
||||
CreateNamesIfNotCreated(&Kill);
|
||||
|
||||
bool KillMsgValid = (Kill.m_aVictimRenderInfo[0].m_CustomColoredSkin && Kill.m_aVictimRenderInfo[0].m_ColorableRenderSkin.m_Body.IsValid()) || (!Kill.m_aVictimRenderInfo[0].m_CustomColoredSkin && Kill.m_aVictimRenderInfo[0].m_OriginalRenderSkin.m_Body.IsValid());
|
||||
KillMsgValid &= Kill.m_KillerID == -1 || ((Kill.m_KillerRenderInfo.m_CustomColoredSkin && Kill.m_KillerRenderInfo.m_ColorableRenderSkin.m_Body.IsValid()) || (!Kill.m_KillerRenderInfo.m_CustomColoredSkin && Kill.m_KillerRenderInfo.m_OriginalRenderSkin.m_Body.IsValid()));
|
||||
if(KillMsgValid)
|
||||
{
|
||||
AddInfoMsg(EType::TYPE_KILL, Kill);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteTextContainers(&Kill);
|
||||
}
|
||||
|
||||
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
}
|
||||
|
||||
if(MsgType == NETMSGTYPE_SV_RACEFINISH)
|
||||
{
|
||||
CNetMsg_Sv_RaceFinish *pMsg = (CNetMsg_Sv_RaceFinish *)pRawMsg;
|
||||
|
||||
char aBuf[256];
|
||||
|
||||
CInfoMsg Finish;
|
||||
Finish.m_TeamSize = 1;
|
||||
Finish.m_aVictimIds[0] = pMsg->m_ClientID;
|
||||
Finish.m_VictimDDTeam = m_pClient->m_Teams.Team(Finish.m_aVictimIds[0]);
|
||||
str_copy(Finish.m_aVictimName, m_pClient->m_aClients[Finish.m_aVictimIds[0]].m_aName);
|
||||
Finish.m_aVictimRenderInfo[0] = m_pClient->m_aClients[pMsg->m_ClientID].m_RenderInfo;
|
||||
|
||||
Finish.m_aKillerName[0] = '\0';
|
||||
|
||||
Finish.m_Diff = pMsg->m_Diff;
|
||||
Finish.m_RecordPersonal = (pMsg->m_RecordPersonal || pMsg->m_RecordServer);
|
||||
|
||||
// diff time text
|
||||
if(Finish.m_Diff)
|
||||
{
|
||||
if(Finish.m_Diff < 0)
|
||||
{
|
||||
str_time_float(-Finish.m_Diff / 1000.0f, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
str_format(Finish.m_aDiffText, sizeof(Finish.m_aDiffText), "(-%s)", aBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_time_float(Finish.m_Diff / 1000.0f, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
str_format(Finish.m_aDiffText, sizeof(Finish.m_aDiffText), "(+%s)", aBuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Finish.m_aDiffText[0] = '\0';
|
||||
}
|
||||
|
||||
// finish time text
|
||||
str_time_float(pMsg->m_Time / 1000.0f, TIME_HOURS_CENTISECS, Finish.m_aTimeText, sizeof(Finish.m_aTimeText));
|
||||
|
||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||
float Height = 400 * 3.0f;
|
||||
float Width = Height * Graphics()->ScreenAspect();
|
||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||
Graphics()->MapScreen(0, 0, Width * 1.5f, Height * 1.5f);
|
||||
|
||||
CreateNamesIfNotCreated(&Finish);
|
||||
CreateFinishTextContainersIfNotCreated(&Finish);
|
||||
|
||||
AddInfoMsg(EType::TYPE_FINISH, Finish);
|
||||
|
||||
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
case NETMSGTYPE_SV_KILLMSGTEAM:
|
||||
OnTeamKillMessage(static_cast<CNetMsg_Sv_KillMsgTeam *>(pRawMsg));
|
||||
break;
|
||||
case NETMSGTYPE_SV_KILLMSG:
|
||||
OnKillMessage(static_cast<CNetMsg_Sv_KillMsg *>(pRawMsg));
|
||||
break;
|
||||
case NETMSGTYPE_SV_RACEFINISH:
|
||||
OnRaceFinishMessage(static_cast<CNetMsg_Sv_RaceFinish *>(pRawMsg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoMessages::RenderKillMsg(CInfoMsg *pInfoMsg, float x, float y)
|
||||
void CInfoMessages::OnTeamKillMessage(const CNetMsg_Sv_KillMsgTeam *pMsg)
|
||||
{
|
||||
std::vector<std::pair<int, int>> vStrongWeakSorted;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_pClient->m_Teams.Team(i) == pMsg->m_Team)
|
||||
{
|
||||
CCharacter *pChr = m_pClient->m_GameWorld.GetCharacterByID(i);
|
||||
vStrongWeakSorted.emplace_back(i, pMsg->m_First == i ? MAX_CLIENTS : pChr ? pChr->GetStrongWeakID() : 0);
|
||||
}
|
||||
}
|
||||
std::stable_sort(vStrongWeakSorted.begin(), vStrongWeakSorted.end(), [](auto &Left, auto &Right) { return Left.second > Right.second; });
|
||||
|
||||
CInfoMsg Kill = CreateInfoMsg(TYPE_KILL);
|
||||
Kill.m_TeamSize = minimum<int>(vStrongWeakSorted.size(), MAX_KILLMSG_TEAM_MEMBERS);
|
||||
|
||||
Kill.m_VictimDDTeam = pMsg->m_Team;
|
||||
for(int i = 0; i < Kill.m_TeamSize; i++)
|
||||
{
|
||||
if(m_pClient->m_aClients[vStrongWeakSorted[i].first].m_Active)
|
||||
{
|
||||
Kill.m_aVictimIds[i] = vStrongWeakSorted[i].first;
|
||||
Kill.m_aVictimRenderInfo[i] = m_pClient->m_aClients[vStrongWeakSorted[i].first].m_RenderInfo;
|
||||
}
|
||||
}
|
||||
str_format(Kill.m_aVictimName, sizeof(Kill.m_aVictimName), Localize("Team %d"), pMsg->m_Team);
|
||||
|
||||
AddInfoMsg(Kill);
|
||||
}
|
||||
|
||||
void CInfoMessages::OnKillMessage(const CNetMsg_Sv_KillMsg *pMsg)
|
||||
{
|
||||
CInfoMsg Kill = CreateInfoMsg(TYPE_KILL);
|
||||
|
||||
Kill.m_TeamSize = 1;
|
||||
Kill.m_aVictimIds[0] = pMsg->m_Victim;
|
||||
Kill.m_VictimDDTeam = m_pClient->m_Teams.Team(Kill.m_aVictimIds[0]);
|
||||
str_copy(Kill.m_aVictimName, m_pClient->m_aClients[Kill.m_aVictimIds[0]].m_aName);
|
||||
Kill.m_aVictimRenderInfo[0] = m_pClient->m_aClients[Kill.m_aVictimIds[0]].m_RenderInfo;
|
||||
|
||||
Kill.m_KillerID = pMsg->m_Killer;
|
||||
str_copy(Kill.m_aKillerName, m_pClient->m_aClients[Kill.m_KillerID].m_aName);
|
||||
Kill.m_KillerRenderInfo = m_pClient->m_aClients[Kill.m_KillerID].m_RenderInfo;
|
||||
|
||||
Kill.m_Weapon = pMsg->m_Weapon;
|
||||
Kill.m_ModeSpecial = pMsg->m_ModeSpecial;
|
||||
Kill.m_FlagCarrierBlue = m_pClient->m_Snap.m_pGameDataObj ? m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue : -1;
|
||||
|
||||
AddInfoMsg(Kill);
|
||||
}
|
||||
|
||||
void CInfoMessages::OnRaceFinishMessage(const CNetMsg_Sv_RaceFinish *pMsg)
|
||||
{
|
||||
CInfoMsg Finish = CreateInfoMsg(TYPE_FINISH);
|
||||
|
||||
Finish.m_TeamSize = 1;
|
||||
Finish.m_aVictimIds[0] = pMsg->m_ClientID;
|
||||
Finish.m_VictimDDTeam = m_pClient->m_Teams.Team(Finish.m_aVictimIds[0]);
|
||||
str_copy(Finish.m_aVictimName, m_pClient->m_aClients[Finish.m_aVictimIds[0]].m_aName);
|
||||
Finish.m_aVictimRenderInfo[0] = m_pClient->m_aClients[pMsg->m_ClientID].m_RenderInfo;
|
||||
|
||||
Finish.m_Diff = pMsg->m_Diff;
|
||||
Finish.m_RecordPersonal = pMsg->m_RecordPersonal || pMsg->m_RecordServer;
|
||||
if(Finish.m_Diff)
|
||||
{
|
||||
char aBuf[64];
|
||||
str_time_float(absolute(Finish.m_Diff) / 1000.0f, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
str_format(Finish.m_aDiffText, sizeof(Finish.m_aDiffText), "(%c%s)", Finish.m_Diff < 0 ? '-' : '+', aBuf);
|
||||
}
|
||||
str_time_float(pMsg->m_Time / 1000.0f, TIME_HOURS_CENTISECS, Finish.m_aTimeText, sizeof(Finish.m_aTimeText));
|
||||
|
||||
AddInfoMsg(Finish);
|
||||
}
|
||||
|
||||
void CInfoMessages::RenderKillMsg(const CInfoMsg &InfoMsg, float x, float y)
|
||||
{
|
||||
// render victim name
|
||||
x -= pInfoMsg->m_VictimTextWidth;
|
||||
ColorRGBA TextColor;
|
||||
if(g_Config.m_ClChatTeamColors && pInfoMsg->m_VictimDDTeam)
|
||||
TextColor = m_pClient->GetDDTeamColor(pInfoMsg->m_VictimDDTeam, 0.75f);
|
||||
if(g_Config.m_ClChatTeamColors && InfoMsg.m_VictimDDTeam)
|
||||
TextColor = m_pClient->GetDDTeamColor(InfoMsg.m_VictimDDTeam, 0.75f);
|
||||
else
|
||||
TextColor = TextRender()->DefaultTextColor();
|
||||
|
||||
CreateNamesIfNotCreated(pInfoMsg);
|
||||
|
||||
if(pInfoMsg->m_VictimTextContainerIndex.Valid())
|
||||
TextRender()->RenderTextContainer(pInfoMsg->m_VictimTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (46.f - 36.f) / 2.f);
|
||||
|
||||
// render victim tee
|
||||
x -= 24.0f;
|
||||
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS)
|
||||
// render victim name
|
||||
if(InfoMsg.m_VictimTextContainerIndex.Valid())
|
||||
{
|
||||
if(pInfoMsg->m_ModeSpecial & 1)
|
||||
{
|
||||
int QuadOffset = 0;
|
||||
if(pInfoMsg->m_aVictimIds[0] == pInfoMsg->m_FlagCarrierBlue)
|
||||
++QuadOffset;
|
||||
|
||||
if(QuadOffset == 0)
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
else
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
|
||||
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x, y - 16);
|
||||
}
|
||||
x -= TextRender()->GetBoundingBoxTextContainer(InfoMsg.m_VictimTextContainerIndex).m_W;
|
||||
TextRender()->RenderTextContainer(InfoMsg.m_VictimTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (ROW_HEIGHT - FONT_SIZE) / 2.0f);
|
||||
}
|
||||
|
||||
for(int j = (pInfoMsg->m_TeamSize - 1); j >= 0; j--)
|
||||
// render victim flag
|
||||
x -= 24.0f;
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj && (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS) && (InfoMsg.m_ModeSpecial & 1))
|
||||
{
|
||||
if(pInfoMsg->m_aVictimIds[j] < 0)
|
||||
int QuadOffset;
|
||||
if(InfoMsg.m_aVictimIds[0] == InfoMsg.m_FlagCarrierBlue)
|
||||
{
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
|
||||
QuadOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
QuadOffset = 1;
|
||||
}
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x, y - 16);
|
||||
}
|
||||
|
||||
// render victim tees
|
||||
for(int j = (InfoMsg.m_TeamSize - 1); j >= 0; j--)
|
||||
{
|
||||
if(InfoMsg.m_aVictimIds[j] < 0)
|
||||
continue;
|
||||
|
||||
const CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &pInfoMsg->m_aVictimRenderInfo[j], OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + 46.0f / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(pIdleState, &pInfoMsg->m_aVictimRenderInfo[j], EMOTE_PAIN, vec2(-1, 0), TeeRenderPos);
|
||||
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(CAnimState::GetIdle(), &InfoMsg.m_aVictimRenderInfo[j], OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + ROW_HEIGHT / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &InfoMsg.m_aVictimRenderInfo[j], EMOTE_PAIN, vec2(-1, 0), TeeRenderPos);
|
||||
x -= 44.0f;
|
||||
}
|
||||
|
||||
// render weapon
|
||||
x -= 32.0f;
|
||||
if(pInfoMsg->m_Weapon >= 0)
|
||||
if(InfoMsg.m_Weapon >= 0)
|
||||
{
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_aSpriteWeapons[pInfoMsg->m_Weapon]);
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, 4 + pInfoMsg->m_Weapon, x, y + 28);
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_aSpriteWeapons[InfoMsg.m_Weapon]);
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, 4 + InfoMsg.m_Weapon, x, y + 28);
|
||||
}
|
||||
x -= 52.0f;
|
||||
|
||||
if(pInfoMsg->m_aVictimIds[0] != pInfoMsg->m_KillerID)
|
||||
// render killer (only if different from victim)
|
||||
if(InfoMsg.m_aVictimIds[0] != InfoMsg.m_KillerID)
|
||||
{
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS)
|
||||
// render killer flag
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj && (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_FLAGS) && (InfoMsg.m_ModeSpecial & 2))
|
||||
{
|
||||
if(pInfoMsg->m_ModeSpecial & 2)
|
||||
int QuadOffset;
|
||||
if(InfoMsg.m_KillerID == InfoMsg.m_FlagCarrierBlue)
|
||||
{
|
||||
int QuadOffset = 2;
|
||||
if(pInfoMsg->m_KillerID == pInfoMsg->m_FlagCarrierBlue)
|
||||
++QuadOffset;
|
||||
|
||||
if(QuadOffset == 2)
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
else
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
|
||||
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x - 56, y - 16);
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
|
||||
QuadOffset = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
|
||||
QuadOffset = 3;
|
||||
}
|
||||
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x - 56, y - 16);
|
||||
}
|
||||
|
||||
// render killer tee
|
||||
x -= 24.0f;
|
||||
|
||||
if(pInfoMsg->m_KillerID >= 0)
|
||||
if(InfoMsg.m_KillerID >= 0)
|
||||
{
|
||||
const CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &pInfoMsg->m_KillerRenderInfo, OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + 46.0f / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(pIdleState, &pInfoMsg->m_KillerRenderInfo, EMOTE_ANGRY, vec2(1, 0), TeeRenderPos);
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(CAnimState::GetIdle(), &InfoMsg.m_KillerRenderInfo, OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + ROW_HEIGHT / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &InfoMsg.m_KillerRenderInfo, EMOTE_ANGRY, vec2(1, 0), TeeRenderPos);
|
||||
}
|
||||
|
||||
x -= 32.0f;
|
||||
|
||||
// render killer name
|
||||
x -= pInfoMsg->m_KillerTextWidth;
|
||||
|
||||
if(pInfoMsg->m_KillerTextContainerIndex.Valid())
|
||||
TextRender()->RenderTextContainer(pInfoMsg->m_KillerTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (46.f - 36.f) / 2.f);
|
||||
if(InfoMsg.m_KillerTextContainerIndex.Valid())
|
||||
{
|
||||
x -= TextRender()->GetBoundingBoxTextContainer(InfoMsg.m_KillerTextContainerIndex).m_W;
|
||||
TextRender()->RenderTextContainer(InfoMsg.m_KillerTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (ROW_HEIGHT - FONT_SIZE) / 2.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoMessages::RenderFinishMsg(CInfoMsg *pInfoMsg, float x, float y)
|
||||
void CInfoMessages::RenderFinishMsg(const CInfoMsg &InfoMsg, float x, float y)
|
||||
{
|
||||
// render time diff
|
||||
CreateFinishTextContainersIfNotCreated(pInfoMsg);
|
||||
|
||||
if(pInfoMsg->m_Diff)
|
||||
if(InfoMsg.m_DiffTextContainerIndex.Valid())
|
||||
{
|
||||
x -= pInfoMsg->m_DiffTextWidth;
|
||||
|
||||
if(pInfoMsg->m_DiffTextContainerIndex.Valid())
|
||||
TextRender()->RenderTextContainer(pInfoMsg->m_DiffTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), x, y + (46.f - 36.f) / 2.f);
|
||||
x -= TextRender()->GetBoundingBoxTextContainer(InfoMsg.m_DiffTextContainerIndex).m_W;
|
||||
TextRender()->RenderTextContainer(InfoMsg.m_DiffTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), x, y + (ROW_HEIGHT - FONT_SIZE) / 2.0f);
|
||||
}
|
||||
|
||||
// render time
|
||||
x -= pInfoMsg->m_TimeTextWidth;
|
||||
|
||||
if(pInfoMsg->m_TimeTextContainerIndex.Valid())
|
||||
TextRender()->RenderTextContainer(pInfoMsg->m_TimeTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), x, y + (46.f - 36.f) / 2.f);
|
||||
if(InfoMsg.m_TimeTextContainerIndex.Valid())
|
||||
{
|
||||
x -= TextRender()->GetBoundingBoxTextContainer(InfoMsg.m_TimeTextContainerIndex).m_W;
|
||||
TextRender()->RenderTextContainer(InfoMsg.m_TimeTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), x, y + (ROW_HEIGHT - FONT_SIZE) / 2.0f);
|
||||
}
|
||||
|
||||
// render flag
|
||||
x -= 52.0f;
|
||||
|
||||
const float FlagSize = 52.0f;
|
||||
x -= FlagSize;
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_RACEFLAG].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
IGraphics::CQuadItem QuadItem(x, y, 52, 52);
|
||||
IGraphics::CQuadItem QuadItem(x, y, FlagSize, FlagSize);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
|
||||
// render victim name
|
||||
ColorRGBA TextColor;
|
||||
x -= pInfoMsg->m_VictimTextWidth;
|
||||
if(g_Config.m_ClChatTeamColors && pInfoMsg->m_VictimDDTeam)
|
||||
TextColor = m_pClient->GetDDTeamColor(pInfoMsg->m_VictimDDTeam, 0.75f);
|
||||
else
|
||||
TextColor = TextRender()->DefaultTextColor();
|
||||
|
||||
CreateNamesIfNotCreated(pInfoMsg);
|
||||
|
||||
if(pInfoMsg->m_VictimTextContainerIndex.Valid())
|
||||
TextRender()->RenderTextContainer(pInfoMsg->m_VictimTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (46.f - 36.f) / 2.f);
|
||||
if(InfoMsg.m_VictimTextContainerIndex.Valid())
|
||||
{
|
||||
x -= TextRender()->GetBoundingBoxTextContainer(InfoMsg.m_VictimTextContainerIndex).m_W;
|
||||
ColorRGBA TextColor;
|
||||
if(g_Config.m_ClChatTeamColors && InfoMsg.m_VictimDDTeam)
|
||||
TextColor = m_pClient->GetDDTeamColor(InfoMsg.m_VictimDDTeam, 0.75f);
|
||||
else
|
||||
TextColor = TextRender()->DefaultTextColor();
|
||||
TextRender()->RenderTextContainer(InfoMsg.m_VictimTextContainerIndex, TextColor, TextRender()->DefaultTextOutlineColor(), x, y + (ROW_HEIGHT - FONT_SIZE) / 2.0f);
|
||||
}
|
||||
|
||||
// render victim tee
|
||||
x -= 24.0f;
|
||||
|
||||
const CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &pInfoMsg->m_aVictimRenderInfo[0], OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + 46.0f / 2.0f + OffsetToMid.y);
|
||||
const int Emote = pInfoMsg->m_RecordPersonal ? EMOTE_HAPPY : EMOTE_NORMAL;
|
||||
RenderTools()->RenderTee(pIdleState, &pInfoMsg->m_aVictimRenderInfo[0], Emote, vec2(-1, 0), TeeRenderPos);
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(CAnimState::GetIdle(), &InfoMsg.m_aVictimRenderInfo[0], OffsetToMid);
|
||||
const vec2 TeeRenderPos = vec2(x, y + ROW_HEIGHT / 2.0f + OffsetToMid.y);
|
||||
const int Emote = InfoMsg.m_RecordPersonal ? EMOTE_HAPPY : EMOTE_NORMAL;
|
||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &InfoMsg.m_aVictimRenderInfo[0], Emote, vec2(-1, 0), TeeRenderPos);
|
||||
}
|
||||
|
||||
void CInfoMessages::OnRender()
|
||||
{
|
||||
float Height = 400 * 3.0f;
|
||||
float Width = Height * Graphics()->ScreenAspect();
|
||||
const float Height = 1.5f * 400.0f * 3.0f;
|
||||
const float Width = Height * Graphics()->ScreenAspect();
|
||||
|
||||
Graphics()->MapScreen(0, 0, Width * 1.5f, Height * 1.5f);
|
||||
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
|
||||
Graphics()->MapScreen(0, 0, Width, Height);
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
float StartX = Width * 1.5f - 10.0f;
|
||||
float y = 30.0f + 100.0f * ((g_Config.m_ClShowfps ? 1 : 0) + (g_Config.m_ClShowpred && Client()->State() != IClient::STATE_DEMOPLAYBACK));
|
||||
const float StartX = Width - 10.0f;
|
||||
const float StartY = 30.0f + (g_Config.m_ClShowfps ? 100.0f : 0.0f) + (g_Config.m_ClShowpred && Client()->State() != IClient::STATE_DEMOPLAYBACK ? 100.0f : 0.0f);
|
||||
|
||||
float y = StartY;
|
||||
for(int i = 1; i <= MAX_INFOMSGS; i++)
|
||||
{
|
||||
CInfoMsg *pInfoMsg = &m_aInfoMsgs[(m_InfoMsgCurrent + i) % MAX_INFOMSGS];
|
||||
if(Client()->GameTick(g_Config.m_ClDummy) > pInfoMsg->m_Tick + Client()->GameTickSpeed() * 10)
|
||||
CInfoMsg &InfoMsg = m_aInfoMsgs[(m_InfoMsgCurrent + i) % MAX_INFOMSGS];
|
||||
if(Client()->GameTick(g_Config.m_ClDummy) > InfoMsg.m_Tick + Client()->GameTickSpeed() * 10)
|
||||
continue;
|
||||
|
||||
if(pInfoMsg->m_Type == EType::TYPE_KILL && g_Config.m_ClShowKillMessages)
|
||||
CreateTextContainersIfNotCreated(InfoMsg);
|
||||
|
||||
if(InfoMsg.m_Type == EType::TYPE_KILL && g_Config.m_ClShowKillMessages)
|
||||
{
|
||||
RenderKillMsg(pInfoMsg, StartX, y);
|
||||
y += 46.0f;
|
||||
RenderKillMsg(InfoMsg, StartX, y);
|
||||
y += ROW_HEIGHT;
|
||||
}
|
||||
else if(pInfoMsg->m_Type == EType::TYPE_FINISH && g_Config.m_ClShowFinishMessages)
|
||||
else if(InfoMsg.m_Type == EType::TYPE_FINISH && g_Config.m_ClShowFinishMessages)
|
||||
{
|
||||
RenderFinishMsg(pInfoMsg, StartX, y);
|
||||
y += 46.0f;
|
||||
RenderFinishMsg(InfoMsg, StartX, y);
|
||||
y += ROW_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
class CInfoMessages : public CComponent
|
||||
{
|
||||
int m_SpriteQuadContainerIndex;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_INFOMSGS = 5,
|
||||
|
@ -20,8 +21,6 @@ class CInfoMessages : public CComponent
|
|||
TYPE_FINISH,
|
||||
};
|
||||
|
||||
public:
|
||||
// info messages
|
||||
struct CInfoMsg
|
||||
{
|
||||
EType m_Type;
|
||||
|
@ -31,12 +30,10 @@ public:
|
|||
int m_VictimDDTeam;
|
||||
char m_aVictimName[64];
|
||||
STextContainerIndex m_VictimTextContainerIndex;
|
||||
float m_VictimTextWidth;
|
||||
CTeeRenderInfo m_aVictimRenderInfo[MAX_KILLMSG_TEAM_MEMBERS];
|
||||
int m_KillerID;
|
||||
char m_aKillerName[64];
|
||||
STextContainerIndex m_KillerTextContainerIndex;
|
||||
float m_KillerTextWidth;
|
||||
CTeeRenderInfo m_KillerRenderInfo;
|
||||
|
||||
// kill msg
|
||||
|
@ -51,25 +48,25 @@ public:
|
|||
char m_aDiffText[32];
|
||||
STextContainerIndex m_TimeTextContainerIndex;
|
||||
STextContainerIndex m_DiffTextContainerIndex;
|
||||
float m_TimeTextWidth;
|
||||
float m_DiffTextWidth;
|
||||
bool m_RecordPersonal;
|
||||
};
|
||||
|
||||
private:
|
||||
void AddInfoMsg(EType Type, CInfoMsg NewMsg);
|
||||
void RenderKillMsg(CInfoMsg *pInfoMsg, float x, float y);
|
||||
void RenderFinishMsg(CInfoMsg *pInfoMsg, float x, float y);
|
||||
|
||||
void CreateNamesIfNotCreated(CInfoMsg *pInfoMsg);
|
||||
void CreateFinishTextContainersIfNotCreated(CInfoMsg *pInfoMsg);
|
||||
|
||||
void DeleteTextContainers(CInfoMsg *pInfoMsg);
|
||||
|
||||
public:
|
||||
CInfoMsg m_aInfoMsgs[MAX_INFOMSGS];
|
||||
int m_InfoMsgCurrent;
|
||||
|
||||
CInfoMsg CreateInfoMsg(EType Type);
|
||||
void AddInfoMsg(const CInfoMsg &InfoMsg);
|
||||
void RenderKillMsg(const CInfoMsg &InfoMsg, float x, float y);
|
||||
void RenderFinishMsg(const CInfoMsg &InfoMsg, float x, float y);
|
||||
|
||||
void OnTeamKillMessage(const struct CNetMsg_Sv_KillMsgTeam *pMsg);
|
||||
void OnKillMessage(const struct CNetMsg_Sv_KillMsg *pMsg);
|
||||
void OnRaceFinishMessage(const struct CNetMsg_Sv_RaceFinish *pMsg);
|
||||
|
||||
void CreateTextContainersIfNotCreated(CInfoMsg &InfoMsg);
|
||||
void DeleteTextContainers(CInfoMsg &InfoMsg);
|
||||
|
||||
public:
|
||||
virtual int Sizeof() const override { return sizeof(*this); }
|
||||
virtual void OnWindowResize() override;
|
||||
virtual void OnRefreshSkins() override;
|
||||
|
|
|
@ -310,26 +310,10 @@ void CSkins::OnInit()
|
|||
|
||||
void CSkins::Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc)
|
||||
{
|
||||
for(const auto &SkinIt : m_Skins)
|
||||
for(const auto &[_, pSkin] : m_Skins)
|
||||
{
|
||||
const auto &pSkin = SkinIt.second;
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Body);
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_BodyOutline);
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Feet);
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_FeetOutline);
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Hands);
|
||||
Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_HandsOutline);
|
||||
for(auto &Eye : pSkin->m_OriginalSkin.m_aEyes)
|
||||
Graphics()->UnloadTexture(&Eye);
|
||||
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Body);
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_BodyOutline);
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Feet);
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_FeetOutline);
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Hands);
|
||||
Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_HandsOutline);
|
||||
for(auto &Eye : pSkin->m_ColorableSkin.m_aEyes)
|
||||
Graphics()->UnloadTexture(&Eye);
|
||||
pSkin->m_OriginalSkin.Unload(Graphics());
|
||||
pSkin->m_ColorableSkin.Unload(Graphics());
|
||||
}
|
||||
|
||||
m_Skins.clear();
|
||||
|
|
|
@ -62,6 +62,11 @@ public:
|
|||
bool m_GotAirJump;
|
||||
int m_TeeRenderFlags;
|
||||
bool m_FeetFlipped;
|
||||
|
||||
bool Valid() const
|
||||
{
|
||||
return m_CustomColoredSkin ? m_ColorableRenderSkin.m_Body.IsValid() : m_OriginalRenderSkin.m_Body.IsValid();
|
||||
}
|
||||
};
|
||||
|
||||
// Tee Render Flags
|
||||
|
|
|
@ -37,6 +37,18 @@ public:
|
|||
for(auto &Eye : m_aEyes)
|
||||
Eye = IGraphics::CTextureHandle();
|
||||
}
|
||||
|
||||
void Unload(IGraphics *pGraphics)
|
||||
{
|
||||
pGraphics->UnloadTexture(&m_Body);
|
||||
pGraphics->UnloadTexture(&m_BodyOutline);
|
||||
pGraphics->UnloadTexture(&m_Feet);
|
||||
pGraphics->UnloadTexture(&m_FeetOutline);
|
||||
pGraphics->UnloadTexture(&m_Hands);
|
||||
pGraphics->UnloadTexture(&m_HandsOutline);
|
||||
for(auto &Eye : m_aEyes)
|
||||
pGraphics->UnloadTexture(&Eye);
|
||||
}
|
||||
};
|
||||
|
||||
SSkinTextures m_OriginalSkin;
|
||||
|
|
Loading…
Reference in a new issue