mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #6459
6459: Add random skin button r=def- a=HiRavie Adds a button for generating a random skin in tee settings. The logic generates handsome tees more often than not. Intentionally didn't add a console command so it's not possible to make annoying skin change binds with this. ![random_skin](https://user-images.githubusercontent.com/65019210/227658839-5e8f3a4b-4e7c-4561-90c9-21a267d61a3a.png) ## Checklist - [x] Tested the change ingame - [x] Provided screenshots if it is a visual change - [x] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [x] Considered possible null pointers and out of bounds array indexing - [x] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: Ravie <65019210+HiRavie@users.noreply.github.com>
This commit is contained in:
commit
214053ec9a
|
@ -105,6 +105,8 @@ class CMenus : public CComponent
|
|||
|
||||
void RefreshSkins();
|
||||
|
||||
void RandomSkin();
|
||||
|
||||
// new gui with gui elements
|
||||
template<typename T>
|
||||
int DoButtonMenu(CUIElement &UIElement, const void *pID, T &&GetTextLambda, int Checked, const CUIRect *pRect, bool HintRequiresStringCheck, bool HintCanChangePositionOrSize = false, int Corners = IGraphics::CORNER_ALL, float r = 5.0f, float FontFactor = 0.0f, vec4 ColorHot = vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4 Color = vec4(1, 1, 1, 0.5f), int AlignVertically = 1)
|
||||
|
|
|
@ -438,6 +438,36 @@ void CMenus::RefreshSkins()
|
|||
}
|
||||
}
|
||||
|
||||
void CMenus::RandomSkin()
|
||||
{
|
||||
static const float s_aSchemes[] = {1.0f / 2.0f, 1.0f / 3.0f, 1.0f / -3.0f, 1.0f / 12.0f, 1.0f / -12.0f}; // complementary, triadic, analogous
|
||||
|
||||
float GoalSat = random_float(0.3f, 1.0f);
|
||||
float MaxBodyLht = 1.0f - GoalSat * GoalSat; // max allowed lightness before we start losing saturation
|
||||
|
||||
ColorHSLA Body;
|
||||
Body.h = random_float();
|
||||
Body.l = random_float(0.0f, MaxBodyLht);
|
||||
Body.s = clamp(GoalSat * GoalSat / (1.0f - Body.l), 0.0f, 1.0f);
|
||||
|
||||
ColorHSLA Feet;
|
||||
Feet.h = std::fmod(Body.h + s_aSchemes[rand() % std::size(s_aSchemes)], 1.0f);
|
||||
Feet.l = random_float();
|
||||
Feet.s = clamp(GoalSat * GoalSat / (1.0f - Feet.l), 0.0f, 1.0f);
|
||||
|
||||
const char *pRandomSkinName = CSkins::VANILLA_SKINS[rand() % (std::size(CSkins::VANILLA_SKINS) - 2)]; // last 2 skins are x_ninja and x_spec
|
||||
|
||||
char *pSkinName = !m_Dummy ? g_Config.m_ClPlayerSkin : g_Config.m_ClDummySkin;
|
||||
unsigned *pColorBody = !m_Dummy ? &g_Config.m_ClPlayerColorBody : &g_Config.m_ClDummyColorBody;
|
||||
unsigned *pColorFeet = !m_Dummy ? &g_Config.m_ClPlayerColorFeet : &g_Config.m_ClDummyColorFeet;
|
||||
|
||||
mem_copy(pSkinName, pRandomSkinName, sizeof(g_Config.m_ClPlayerSkin));
|
||||
*pColorBody = Body.Pack(false);
|
||||
*pColorFeet = Feet.Pack(false);
|
||||
|
||||
SetNeedSendInfo();
|
||||
}
|
||||
|
||||
void CMenus::Con_AddFavoriteSkin(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
auto *pSelf = (CMenus *)pUserData;
|
||||
|
@ -601,7 +631,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
OwnSkinInfo.m_Size = 50.0f;
|
||||
|
||||
MainView.HSplitTop(50.0f, &Label, &MainView);
|
||||
Label.VSplitLeft(230.0f, &Label, 0);
|
||||
Label.VSplitLeft(260.0f, &Label, 0);
|
||||
CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
vec2 OffsetToMid;
|
||||
RenderTools()->GetRenderTeeOffsetToRenderedTee(pIdleState, &OwnSkinInfo, OffsetToMid);
|
||||
|
@ -661,6 +691,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
RenderTools()->RenderTee(pIdleState, &OwnSkinInfo, CurrentEyeEmote, vec2(1, 0), vec2(EyesTee.x + 25.0f, EyesTee.y + EyesTee.h / 2.0f + OffsetToMid.y));
|
||||
}
|
||||
|
||||
Label.VSplitRight(34.0f, &Label, &Button);
|
||||
|
||||
static float s_OffsetSkin = 0.0f;
|
||||
static int s_ClearButton = 0;
|
||||
SUIExEditBoxProperties EditProps;
|
||||
|
@ -670,6 +702,22 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
SetNeedSendInfo();
|
||||
}
|
||||
|
||||
// random skin button
|
||||
Button.VSplitRight(30.0f, 0, &Button);
|
||||
static CButtonContainer s_RandomSkinButtonID;
|
||||
static const char *s_apDice[] = {"\xef\x94\xa5", "\xef\x94\xa8", "\xef\x94\xa7", "\xef\x94\xa4", "\xef\x94\xa3", "\xef\x94\xa6"};
|
||||
static int s_CurrentDie = rand() % std::size(s_apDice);
|
||||
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
if(DoButton_Menu(&s_RandomSkinButtonID, s_apDice[s_CurrentDie], 1, &Button, nullptr, IGraphics::CORNER_ALL, 5.0f, -0.2f))
|
||||
{
|
||||
RandomSkin();
|
||||
s_CurrentDie = rand() % std::size(s_apDice);
|
||||
}
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->SetCurFont(nullptr);
|
||||
GameClient()->m_Tooltips.DoToolTip(&s_RandomSkinButtonID, &Button, Localize("Create a random skin"));
|
||||
|
||||
// custom color selector
|
||||
MainView.HSplitTop(20.0f + RenderEyesBelow * 25.0f, 0, &MainView);
|
||||
MainView.HSplitTop(20.0f, &Button, &MainView);
|
||||
|
|
|
@ -17,12 +17,7 @@
|
|||
|
||||
#include "skins.h"
|
||||
|
||||
static const char *VANILLA_SKINS[] = {"bluekitty", "bluestripe", "brownbear",
|
||||
"cammo", "cammostripes", "coala", "default", "limekitty",
|
||||
"pinky", "redbopp", "redstripe", "saddo", "toptri",
|
||||
"twinbop", "twintri", "warpaint", "x_ninja", "x_spec"};
|
||||
|
||||
static bool IsVanillaSkin(const char *pName)
|
||||
bool CSkins::IsVanillaSkin(const char *pName)
|
||||
{
|
||||
return std::any_of(std::begin(VANILLA_SKINS), std::end(VANILLA_SKINS), [pName](const char *pVanillaSkin) { return str_comp(pName, pVanillaSkin) == 0; });
|
||||
}
|
||||
|
|
|
@ -69,6 +69,13 @@ public:
|
|||
|
||||
bool IsDownloadingSkins() { return m_DownloadingSkins; }
|
||||
|
||||
static bool IsVanillaSkin(const char *pName);
|
||||
|
||||
constexpr static const char *VANILLA_SKINS[] = {"bluekitty", "bluestripe", "brownbear",
|
||||
"cammo", "cammostripes", "coala", "default", "limekitty",
|
||||
"pinky", "redbopp", "redstripe", "saddo", "toptri",
|
||||
"twinbop", "twintri", "warpaint", "x_ninja", "x_spec"};
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string_view, std::unique_ptr<CSkin>> m_Skins;
|
||||
std::unordered_map<std::string_view, std::unique_ptr<CDownloadSkin>> m_DownloadSkins;
|
||||
|
|
Loading…
Reference in a new issue