From 1182180e2321b750c93d839a217253982d541882 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Sat, 7 Jan 2023 09:20:25 +0100 Subject: [PATCH] Add skin to serverbrowser player list --- src/engine/serverbrowser.h | 6 +++ src/engine/shared/serverinfo.cpp | 41 +++++++++++++++ src/engine/shared/serverinfo.h | 4 ++ src/game/client/components/menus_browser.cpp | 53 ++++++++++++++++++-- 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index a4b194b1d..ebdc1eba7 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -42,6 +42,12 @@ public: int m_Score; bool m_Player; + // skin info + char m_aSkin[24 + 1]; + bool m_CustomSkinColors; + int m_CustomSkinColorBody; + int m_CustomSkinColorFeet; + int m_FriendState; }; diff --git a/src/engine/shared/serverinfo.cpp b/src/engine/shared/serverinfo.cpp index 6f045d513..2e5236603 100644 --- a/src/engine/shared/serverinfo.cpp +++ b/src/engine/shared/serverinfo.cpp @@ -119,6 +119,42 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson) pClient->m_Country = json_int_get(&Country); pClient->m_Score = json_int_get(&Score); pClient->m_IsPlayer = IsPlayer; + + // check if a skin is also available + bool HasSkin = false; + const json_value &SkinObj = Client["skin"]; + if(SkinObj.type == json_object) + { + const json_value &SkinName = SkinObj["name"]; + const json_value &SkinBodyColor = SkinObj["color_body"]; + const json_value &SkinFeetColor = SkinObj["color_feet"]; + if(SkinName.type == json_string) + { + HasSkin = true; + str_copy(pClient->m_aSkin, json_string_get(&SkinName)); + // if skin json value existed, then always at least default to "default" + if(pClient->m_aSkin[0] == '\0') + str_copy(pClient->m_aSkin, "default"); + // if skin also has custom colors, add them + if(SkinBodyColor.type == json_integer && SkinFeetColor.type == json_integer) + { + pClient->m_CustomSkinColors = true; + pClient->m_CustomSkinColorBody = json_int_get(&SkinBodyColor); + pClient->m_CustomSkinColorFeet = json_int_get(&SkinFeetColor); + } + // else set custom colors off + else + { + pClient->m_CustomSkinColors = false; + } + } + } + + // else make it null terminated + if(!HasSkin) + { + pClient->m_aSkin[0] = '\0'; + } } pOut->m_NumClients++; @@ -183,6 +219,11 @@ CServerInfo2::operator CServerInfo() const Result.m_aClients[i].m_Country = m_aClients[i].m_Country; Result.m_aClients[i].m_Score = m_aClients[i].m_Score; Result.m_aClients[i].m_Player = m_aClients[i].m_IsPlayer; + + str_copy(Result.m_aClients[i].m_aSkin, m_aClients[i].m_aSkin); + Result.m_aClients[i].m_CustomSkinColors = m_aClients[i].m_CustomSkinColors; + Result.m_aClients[i].m_CustomSkinColorBody = m_aClients[i].m_CustomSkinColorBody; + Result.m_aClients[i].m_CustomSkinColorFeet = m_aClients[i].m_CustomSkinColorFeet; } Result.m_NumReceivedClients = minimum(m_NumClients, (int)SERVERINFO_MAX_CLIENTS); diff --git a/src/engine/shared/serverinfo.h b/src/engine/shared/serverinfo.h index 84f366c00..f32c97fa9 100644 --- a/src/engine/shared/serverinfo.h +++ b/src/engine/shared/serverinfo.h @@ -18,6 +18,10 @@ public: int m_Country; int m_Score; bool m_IsPlayer; + char m_aSkin[24 + 1]; + bool m_CustomSkinColors; + int m_CustomSkinColorBody; + int m_CustomSkinColorFeet; }; CClient m_aClients[SERVERINFO_MAX_CLIENTS]; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index f5ece6897..9ec3a8e0d 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -1105,16 +1106,29 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) if(!Item.m_Visible) continue; - CUIRect Name, Clan, Score, Flag; + const bool HasTeeToRender = pSelectedServer->m_aClients[i].m_aSkin[0] != '\0'; + + CUIRect Skin, Name, Clan, Score, Flag; Name = Item.m_Rect; ColorRGBA Color = CurrentClient.m_FriendState == IFriends::FRIEND_NO ? ColorRGBA(1.0f, 1.0f, 1.0f, (i % 2 + 1) * 0.05f) : ColorRGBA(0.5f, 1.0f, 0.5f, 0.15f + (i % 2 + 1) * 0.05f); Name.Draw(Color, IGraphics::CORNER_ALL, 4.0f); - Name.VSplitLeft(5.0f, 0, &Name); + if(HasTeeToRender) + { + Name.VSplitLeft(1.0f, nullptr, &Name); + } Name.VSplitLeft(34.0f, &Score, &Name); - Name.VSplitRight(34.0f, &Name, &Flag); + if(HasTeeToRender) + { + Name.VSplitLeft(18.0f, &Skin, &Name); + } + else + { + Name.VSplitLeft(5.0f, 0, &Name); + } + Name.VSplitRight(HasTeeToRender ? 20.0 : 34.0f, &Name, &Flag); Flag.HMargin(4.0f, &Flag); Name.HSplitTop(12.0f, &Name, &Clan); @@ -1141,6 +1155,35 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) Cursor.m_LineWidth = Score.w; TextRender()->TextEx(&Cursor, aTemp, -1); + // render tee if available + if(HasTeeToRender) + { + CTeeRenderInfo TeeInfo; + const CSkin *pSkin = m_pClient->m_Skins.Find(CurrentClient.m_aSkin); + TeeInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin; + TeeInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin; + TeeInfo.m_SkinMetrics = pSkin->m_Metrics; + TeeInfo.m_CustomColoredSkin = CurrentClient.m_CustomSkinColors; + if(CurrentClient.m_CustomSkinColors) + { + TeeInfo.m_ColorBody = color_cast(ColorHSLA(CurrentClient.m_CustomSkinColorBody).UnclampLighting()); + TeeInfo.m_ColorFeet = color_cast(ColorHSLA(CurrentClient.m_CustomSkinColorFeet).UnclampLighting()); + } + else + { + TeeInfo.m_ColorBody = ColorRGBA(1.0f, 1.0f, 1.0f); + TeeInfo.m_ColorFeet = ColorRGBA(1.0f, 1.0f, 1.0f); + } + TeeInfo.m_Size = minimum(Skin.w, Skin.h); + + CAnimState *pIdleState = CAnimState::GetIdle(); + vec2 OffsetToMid; + RenderTools()->GetRenderTeeOffsetToRenderedTee(pIdleState, &TeeInfo, OffsetToMid); + vec2 TeeRenderPos(Skin.x + TeeInfo.m_Size / 2, Skin.y + Skin.h / 2 + OffsetToMid.y); + + RenderTools()->RenderTee(pIdleState, &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), TeeRenderPos); + } + // name TextRender()->SetCursor(&Cursor, Name.x, Name.y + (Name.h - (FontSize - 2)) / 2.f, FontSize - 2, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Name.w; @@ -1175,7 +1218,9 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) // flag ColorRGBA FColor(1.0f, 1.0f, 1.0f, 0.5f); - m_pClient->m_CountryFlags.Render(CurrentClient.m_Country, &FColor, Flag.x, Flag.y, Flag.w, Flag.h); + m_pClient->m_CountryFlags.Render(CurrentClient.m_Country, &FColor, Flag.x, + Flag.y + ((Flag.h - Flag.w / 2) / 2), + Flag.w, Flag.w / 2); } const int NewSelected = s_ListBox.DoEnd();