diff --git a/src/engine/shared/tater_variables.h b/src/engine/shared/tater_variables.h index ca2aec642a8..52896dec6e9 100644 --- a/src/engine/shared/tater_variables.h +++ b/src/engine/shared/tater_variables.h @@ -142,6 +142,7 @@ MACRO_CONFIG_INT(ClWarList, tc_warlist, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, MACRO_CONFIG_INT(ClWarListShowClan, tc_warlist_show_clan_if_war, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show clan in nameplate if there is a war") MACRO_CONFIG_INT(ClWarListReason, tc_warlist_reason, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show war reason") MACRO_CONFIG_INT(ClWarListChat, tc_warlist_chat, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show war colors in chat") +MACRO_CONFIG_INT(ClWarListScoreboard, tc_warlist_scoreboard, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show war colors in scoreboard") // AAAAAAA MACRO_CONFIG_INT(ClAmIFrozen, EEEfrz, 0, 0, 1, CFGFLAG_CLIENT, "") diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 2392216a58f..8b17745efbe 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -1079,6 +1079,8 @@ void CChat::OnPrepareLines(float y) NameColor = color_cast(ColorHSLA(g_Config.m_ClMessageSystemColor)); else if(Line.m_ClientId == CLIENT_MSG) NameColor = color_cast(ColorHSLA(g_Config.m_ClMessageClientColor)); + else if(Line.m_ClientId >= 0 && g_Config.m_ClWarList && g_Config.m_ClWarListChat && GameClient()->m_WarList.GetAnyWar(Line.m_ClientId)) // TClient + NameColor = GameClient()->m_WarList.GetPriorityColor(Line.m_ClientId); else if(Line.m_Team) NameColor = CalculateNameColor(ColorHSLA(g_Config.m_ClMessageTeamColor)); else if(Line.m_NameColor == TEAM_RED) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 33692b4daf3..5da6ea9cdba 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -615,7 +615,13 @@ void CHud::RenderTextInfo() TextRender()->Text(4.0f, OffsetY, FontSize, aBuf, -1.0f); } } - + if(g_Config.m_ClRenderCursorSpec && m_pClient->m_Snap.m_SpecInfo.m_SpectatorId == SPEC_FREEVIEW) + { + int CurWeapon = 1; + Graphics()->SetColor(1.f, 1.f, 1.f, g_Config.m_ClRenderCursorSpecAlpha / 100.0f); + Graphics()->TextureSet(m_pClient->m_GameSkin.m_aSpriteWeaponCursors[CurWeapon]); + Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, m_aCursorOffset[CurWeapon], m_Width / 2.0f, m_Height / 2.0f, 0.36f, 0.36f); + } // render team in freeze text and last notify if((g_Config.m_ClShowFrozenText > 0 || g_Config.m_ClShowFrozenHud > 0 || g_Config.m_ClNotifyWhenLast) && GameClient()->m_GameInfo.m_EntitiesDDRace) { diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index 5338934a37e..a9cb333396c 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -98,6 +98,36 @@ void CNamePlate::CNamePlateHookWeakStrongId::Update(CNamePlates &This, int Id, f This.Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } +// TClient +void CNamePlate::CNamePlateSkin::Update(CNamePlates &This, const char *pSkin, float FontSize) +{ + if(str_comp(m_aSkin, pSkin) == 0 && m_FontSize == FontSize) + return; + str_copy(m_aSkin, pSkin); + m_FontSize = FontSize; + float ScreenX0, ScreenY0, ScreenX1, ScreenY1; + This.Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); + This.RenderTools()->MapScreenToInterface(This.m_pClient->m_Camera.m_Center.x, This.m_pClient->m_Camera.m_Center.y); + CTextCursor Cursor; + This.TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, FontSize, TEXTFLAG_RENDER); + This.TextRender()->RecreateTextContainer(m_TextContainerIndex, &Cursor, m_aSkin); + This.Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); +} +void CNamePlate::CNamePlateReason::Update(CNamePlates &This, const char *pReason, float FontSize) +{ + if(str_comp(m_aReason, pReason) == 0 && m_FontSize == FontSize) + return; + str_copy(m_aReason, pReason); + m_FontSize = FontSize; + float ScreenX0, ScreenY0, ScreenX1, ScreenY1; + This.Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); + This.RenderTools()->MapScreenToInterface(This.m_pClient->m_Camera.m_Center.x, This.m_pClient->m_Camera.m_Center.y); + CTextCursor Cursor; + This.TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, FontSize, TEXTFLAG_RENDER); + This.TextRender()->RecreateTextContainer(m_TextContainerIndex, &Cursor, m_aReason); + This.Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); +} + void CNamePlates::RenderNamePlate(CNamePlate &NamePlate, const CRenderNamePlateData &Data) { ColorRGBA OutlineColor = Data.m_OutlineColor.WithAlpha(Data.m_Alpha / 2.0f); @@ -107,9 +137,67 @@ void CNamePlates::RenderNamePlate(CNamePlate &NamePlate, const CRenderNamePlateD // Render directions TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_NO_FIRST_CHARACTER_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_LAST_CHARACTER_ADVANCE); + + if((Data.m_pName && Data.m_pName[0] != '\0') || Data.m_ClientId >= 0 || Data.m_ShowFriendMark) + { + YOffset -= Data.m_FontSize; + NamePlate.m_Name.Update(*this, Data.m_ClientId, Data.m_pName, Data.m_ShowFriendMark, Data.m_FontSize); + + //TClient + if(Data.m_IsGame && Data.m_RealClientId >= 0) + if((g_Config.m_ClPingNameCircle || (m_pClient->m_Scoreboard.Active() && !m_pClient->m_Snap.m_apPlayerInfos[Data.m_RealClientId]->m_Local)) && !(Client()->State() == IClient::STATE_DEMOPLAYBACK)) + { + Graphics()->TextureClear(); + Graphics()->QuadsBegin(); + Graphics()->SetColor(color_cast(ColorHSLA((300.0f - clamp(m_pClient->m_Snap.m_apPlayerInfos[Data.m_RealClientId]->m_Latency, 0, 300)) / 1000.0f, 1.0f, 0.5f, 0.8f)).WithAlpha(Data.m_Alpha)); + float CircleSize = 7.0f; + Graphics()->DrawCircle(Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Name.m_TextContainerIndex).m_W / 2.0f - CircleSize, YOffset + Data.m_FontSize / 2.0f + 1.4f, CircleSize, 24); + Graphics()->QuadsEnd(); + } + ColorRGBA WarColor = Color; + if(Data.m_IsGame && Data.m_RealClientId >= 0 && !Data.m_ShowClanWarInName && GameClient()->m_WarList.GetWarData(Data.m_RealClientId).IsWarName) + WarColor = GameClient()->m_WarList.GetNameplateColor(Data.m_RealClientId).WithAlpha(Data.m_Alpha); + else if(Data.m_IsGame && Data.m_RealClientId >= 0 && Data.m_ShowClanWarInName && GameClient()->m_WarList.GetWarData(Data.m_RealClientId).IsWarClan) + WarColor = GameClient()->m_WarList.GetClanColor(Data.m_RealClientId).WithAlpha(Data.m_Alpha); + + if(NamePlate.m_Name.m_TextContainerIndex.Valid()) + TextRender()->RenderTextContainer(NamePlate.m_Name.m_TextContainerIndex, WarColor, OutlineColor, Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Name.m_TextContainerIndex).m_W / 2.0f, YOffset); + } + + if(Data.m_pClan && Data.m_pClan[0] != '\0') + { + YOffset -= Data.m_FontSizeClan; + NamePlate.m_Clan.Update(*this, Data.m_pClan, Data.m_FontSizeClan); + + ColorRGBA WarColor = Color; + if(Data.m_IsGame && Data.m_RealClientId >= 0 && GameClient()->m_WarList.GetWarData(Data.m_RealClientId).IsWarClan) + WarColor = GameClient()->m_WarList.GetClanColor(Data.m_RealClientId).WithAlpha(Data.m_Alpha); + + if(NamePlate.m_Clan.m_TextContainerIndex.Valid()) + TextRender()->RenderTextContainer(NamePlate.m_Clan.m_TextContainerIndex, WarColor, OutlineColor, Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Clan.m_TextContainerIndex).m_W / 2.0f, YOffset); + } + + // TClient war reason + if(Data.m_IsGame && !Data.m_IsLocal && Data.m_RealClientId >= 0 && g_Config.ms_ClWarList && GameClient()->m_WarList.GetWarData(Data.m_RealClientId).m_aReason[0] != '\0') + { + YOffset -= Data.m_FontSizeClan; + NamePlate.m_Reason.Update(*this, GameClient()->m_WarList.GetWarData(Data.m_RealClientId).m_aReason, Data.m_FontSizeClan); + if(NamePlate.m_Reason.m_TextContainerIndex.Valid()) + TextRender()->RenderTextContainer(NamePlate.m_Reason.m_TextContainerIndex, Data.m_Color.WithAlpha(Data.m_Alpha * 0.5f), Data.m_OutlineColor.WithAlpha(Data.m_Alpha / 4.0f), Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Reason.m_TextContainerIndex).m_W / 2.0f, YOffset); + } + //TClient tc_skin_name + if(Data.m_IsGame && !Data.m_IsLocal && Data.m_RealClientId >= 0 && g_Config.m_ClShowSkinName) + { + YOffset -= Data.m_FontSizeClan; + NamePlate.m_SkinName.Update(*this, GameClient()->m_aClients[Data.m_RealClientId].m_aSkinName, Data.m_FontSizeClan); + if(NamePlate.m_SkinName.m_TextContainerIndex.Valid()) + TextRender()->RenderTextContainer(NamePlate.m_SkinName.m_TextContainerIndex, Color, OutlineColor, Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_SkinName.m_TextContainerIndex).m_W / 2.0f, YOffset); + } + if(Data.m_ShowDirection) { Graphics()->SetColor(1.0f, 1.0f, 1.0f, Data.m_Alpha); + YOffset -= 6.5f; //TClient YOffset -= Data.m_FontSizeDirection; const vec2 ShowDirectionPos = vec2(Data.m_Position.x - Data.m_FontSizeDirection / 2.0f, YOffset + Data.m_FontSizeDirection / 2.0f); if(Data.m_DirLeft) @@ -134,21 +222,6 @@ void CNamePlates::RenderNamePlate(CNamePlate &NamePlate, const CRenderNamePlateD Graphics()->QuadsSetRotation(0.0f); } - if((Data.m_pName && Data.m_pName[0] != '\0') || Data.m_ClientId >= 0 || Data.m_ShowFriendMark) - { - YOffset -= Data.m_FontSize; - NamePlate.m_Name.Update(*this, Data.m_ClientId, Data.m_pName, Data.m_ShowFriendMark, Data.m_FontSize); - if(NamePlate.m_Name.m_TextContainerIndex.Valid()) - TextRender()->RenderTextContainer(NamePlate.m_Name.m_TextContainerIndex, Color, OutlineColor, Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Name.m_TextContainerIndex).m_W / 2.0f, YOffset); - } - if(Data.m_pClan && Data.m_pClan[0] != '\0') - { - YOffset -= Data.m_FontSizeClan; - NamePlate.m_Clan.Update(*this, Data.m_pClan, Data.m_FontSizeClan); - if(NamePlate.m_Clan.m_TextContainerIndex.Valid()) - TextRender()->RenderTextContainer(NamePlate.m_Clan.m_TextContainerIndex, Color, OutlineColor, Data.m_Position.x - TextRender()->GetBoundingBoxTextContainer(NamePlate.m_Clan.m_TextContainerIndex).m_W / 2.0f, YOffset); - } - if(Data.m_ShowHookWeakStrongId || (Data.m_ShowHookWeakStrong && Data.m_HookWeakStrong != TRISTATE::SOME)) // Don't show hook icon if there's no ID or hook strength to show { ColorRGBA HookWeakStrongColor; @@ -220,13 +293,22 @@ void CNamePlates::RenderNamePlateGame(vec2 Position, const CNetObj_PlayerInfo *p bool ShowNamePlate = pPlayerInfo->m_Local ? g_Config.m_ClNamePlatesOwn : g_Config.m_ClNamePlates; + // TClient + Data.m_RealClientId = pPlayerInfo->m_ClientId; + Data.m_IsGame = true; + bool ClanPlateOverride = g_Config.m_ClWarList && g_Config.m_ClWarListShowClan && GameClient()->m_WarList.GetWarData(pPlayerInfo->m_ClientId).IsWarClan; + bool ShowClanPlate = g_Config.m_ClNamePlatesClan || ClanPlateOverride; + bool ShowClanWarInName = g_Config.m_ClWarList && !ShowClanPlate && GameClient()->m_WarList.GetWarData(pPlayerInfo->m_ClientId).IsWarClan && !GameClient()->m_WarList.GetWarData(pPlayerInfo->m_ClientId).IsWarName; + Data.m_ShowClanWarInName = ShowClanWarInName; + Data.m_IsLocal = pPlayerInfo->m_Local; + Data.m_Position = Position; Data.m_ClientId = ShowNamePlate && g_Config.m_ClNamePlatesIds ? pPlayerInfo->m_ClientId : -1; Data.m_pName = ShowNamePlate ? m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_aName : nullptr; Data.m_ShowFriendMark = ShowNamePlate && g_Config.m_ClNamePlatesFriendMark && m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_Friend; Data.m_FontSize = 18.0f + 20.0f * g_Config.m_ClNamePlatesSize / 100.0f; - Data.m_pClan = ShowNamePlate && g_Config.m_ClNamePlatesClan ? m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_aClan : nullptr; + Data.m_pClan = ShowNamePlate && ShowClanPlate ? m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_aClan : nullptr; Data.m_FontSizeClan = 18.0f + 20.0f * g_Config.m_ClNamePlatesClanSize / 100.0f; Data.m_FontSizeHookWeakStrong = 18.0f + 20.0f * g_Config.m_ClNamePlatesStrongSize / 100.0f; diff --git a/src/game/client/components/nameplates.h b/src/game/client/components/nameplates.h index 5c20f2473da..6b976f6f75b 100644 --- a/src/game/client/components/nameplates.h +++ b/src/game/client/components/nameplates.h @@ -84,16 +84,63 @@ class CNamePlate m_Name.Reset(); m_Clan.Reset(); m_WeakStrongId.Reset(); + + //TClient + m_SkinName.Reset(); + m_Reason.Reset(); } void DeleteTextContainers(ITextRender &TextRender) { TextRender.DeleteTextContainer(m_Name.m_TextContainerIndex); TextRender.DeleteTextContainer(m_Clan.m_TextContainerIndex); TextRender.DeleteTextContainer(m_WeakStrongId.m_TextContainerIndex); + TextRender.DeleteTextContainer(m_SkinName.m_TextContainerIndex); + TextRender.DeleteTextContainer(m_Reason.m_TextContainerIndex); + } CNamePlateName m_Name; CNamePlateClan m_Clan; CNamePlateHookWeakStrongId m_WeakStrongId; + + // TClient + class CNamePlateSkin + { + public: + CNamePlateSkin() + { + Reset(); + } + void Reset() + { + m_TextContainerIndex.Reset(); + m_aSkin[0] = '\0'; + m_FontSize = -INFINITY; + } + void Update(CNamePlates &This, const char *pSkin, float FontSize); + STextContainerIndex m_TextContainerIndex; + char m_aSkin[MAX_SKIN_LENGTH]; + float m_FontSize; + }; + class CNamePlateReason + { + public: + CNamePlateReason() + { + Reset(); + } + void Reset() + { + m_TextContainerIndex.Reset(); + m_aReason[0] = '\0'; + m_FontSize = -INFINITY; + } + void Update(CNamePlates &This, const char *pReason, float FontSize); + STextContainerIndex m_TextContainerIndex; + char m_aReason[MAX_WARLIST_REASON_LENGTH]; + float m_FontSize; + }; + CNamePlateSkin m_SkinName; + CNamePlateReason m_Reason; }; class CNamePlates : public CComponent @@ -102,6 +149,11 @@ class CNamePlates : public CComponent friend class CNamePlate::CNamePlateClan; friend class CNamePlate::CNamePlateHookWeakStrongId; + //TClient + friend class CNamePlate::CNamePlateSkin; + friend class CNamePlate::CNamePlateReason; + + CNamePlate m_aNamePlates[MAX_CLIENTS]; void ResetNamePlates(); @@ -130,6 +182,12 @@ class CNamePlates : public CComponent bool m_ShowHookWeakStrongId; int m_HookWeakStrongId; float m_FontSizeHookWeakStrong; + + //TClient + int m_RealClientId; + bool m_IsGame = false; + bool m_ShowClanWarInName = false; + bool m_IsLocal = false; }; void RenderNamePlate(CNamePlate &NamePlate, const CRenderNamePlateData &Data); diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index e2e449ddc37..fa3b3b82440 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -243,8 +243,6 @@ void CPlayers::RenderHookCollLine( #endif if((AlwaysRenderHookColl || RenderHookCollPlayer) && RenderHookCollVideo) { - vec2 ExDirection = Direction; - if(Local && !m_pClient->m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK) { ExDirection = normalize( diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 33d2fd4527f..f487fe6441d 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -544,6 +544,11 @@ void CScoreboard::RenderScoreboard(CUIRect Scoreboard, int Team, int CountStart, GameClient()->FormatClientId(pInfo->m_ClientId, aClientId, EClientIdFormat::INDENT_AUTO); TextRender()->TextEx(&Cursor, aClientId); } + + // TClient + if(pInfo->m_ClientId >= 0 && g_Config.m_ClWarList && g_Config.m_ClWarListScoreboard && GameClient()->m_WarList.GetAnyWar(pInfo->m_ClientId)) + TextRender()->TextColor(GameClient()->m_WarList.GetNameplateColor(pInfo->m_ClientId)); + TextRender()->TextEx(&Cursor, ClientData.m_aName); // ready / watching @@ -564,6 +569,11 @@ void CScoreboard::RenderScoreboard(CUIRect Scoreboard, int Team, int CountStart, { TextRender()->TextColor(TextColor); } + + // TClient + if(pInfo->m_ClientId >= 0 && g_Config.m_ClWarList && g_Config.m_ClWarListScoreboard && GameClient()->m_WarList.GetAnyWar(pInfo->m_ClientId)) + TextRender()->TextColor(GameClient()->m_WarList.GetClanColor(pInfo->m_ClientId)); + CTextCursor Cursor; TextRender()->SetCursor(&Cursor, ClanOffset + (ClanLength - minimum(TextRender()->TextWidth(FontSize, ClientData.m_aClan), ClanLength)) / 2.0f, Row.y + (Row.h - FontSize) / 2.0f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_ELLIPSIS_AT_END); Cursor.m_LineWidth = ClanLength; diff --git a/src/game/client/components/tclient/warlist.cpp b/src/game/client/components/tclient/warlist.cpp index cd223d11e84..6d813f4be20 100644 --- a/src/game/client/components/tclient/warlist.cpp +++ b/src/game/client/components/tclient/warlist.cpp @@ -230,6 +230,14 @@ CWarEntry *CWarList::FindWarEntry(const char *pName, const char *pClan, const ch return nullptr; } +ColorRGBA CWarList::GetPriorityColor(int ClientId) +{ + if(m_WarPlayers[ClientId].IsWarClan && !m_WarPlayers[ClientId].IsWarName) + return m_WarPlayers[ClientId].m_ClanColor; + else + return m_WarPlayers[ClientId].m_NameColor; +} + ColorRGBA CWarList::GetNameplateColor(int ClientId) { return m_WarPlayers[ClientId].m_NameColor; @@ -238,6 +246,10 @@ ColorRGBA CWarList::GetClanColor(int ClientId) { return m_WarPlayers[ClientId].m_ClanColor; } +bool CWarList::GetAnyWar(int ClientId) +{ + return m_WarPlayers[ClientId].IsWarClan || m_WarPlayers[ClientId].IsWarName; +} void CWarList::GetReason(char *pReason, int ClientId) { diff --git a/src/game/client/components/tclient/warlist.h b/src/game/client/components/tclient/warlist.h index 04032a1174f..8cd62cbb8e9 100644 --- a/src/game/client/components/tclient/warlist.h +++ b/src/game/client/components/tclient/warlist.h @@ -178,8 +178,11 @@ class CWarList : public CComponent void RemoveWarEntry(int Index); void RemoveWarType(int Index); + ColorRGBA GetPriorityColor(int ClientId); ColorRGBA GetNameplateColor(int ClientId); ColorRGBA GetClanColor(int ClientId); + bool GetAnyWar(int ClientId); + void GetReason(char *pReason, int ClientId); CWarDataCache GetWarData(int ClientId);