Skip to content

Commit d725125

Browse files
[Holiday] Custom rainbows (#4698)
* [Holiday] Custom rainbows * Update soh/soh/Enhancements/Holiday/LL.h Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> --------- Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
1 parent a10b4d0 commit d725125

File tree

3 files changed

+254
-3
lines changed

3 files changed

+254
-3
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#include "Holiday.hpp"
2+
#include "LL.h"
3+
4+
extern "C" {
5+
#include "macros.h"
6+
#include "functions.h"
7+
#include "variables.h"
8+
extern PlayState* gPlayState;
9+
10+
// TODO: Include anything you need here from C land
11+
}
12+
13+
// TODO: Change this to YourName
14+
#define AUTHOR "LL"
15+
#define CVAR(v) "gHoliday." AUTHOR "." v
16+
17+
static ImVec4 customColorZero = RAINBOW_PRESETS[0][0];
18+
static ImVec4 customColorOne = RAINBOW_PRESETS[0][1];
19+
static ImVec4 customColorMinusZero = RAINBOW_PRESETS[0][2];
20+
static ImVec4 customColorMinusOne = RAINBOW_PRESETS[0][3];
21+
22+
ImVec4 Color_LUSToImGui(Color_RGBA8 color) {
23+
ImVec4 result;
24+
25+
result.x = color.r / 255.0f;
26+
result.y = color.g / 255.0f;
27+
result.z = color.b / 255.0f;
28+
result.w = color.a / 255.0f;
29+
30+
return result;
31+
}
32+
33+
Color_RGBA8 Color_ImGuiToLUS(ImVec4 color) {
34+
Color_RGBA8 result;
35+
36+
result.r = static_cast<uint8_t>(color.x * 255);
37+
result.g = static_cast<uint8_t>(color.y * 255);
38+
result.b = static_cast<uint8_t>(color.z * 255);
39+
result.a = static_cast<uint8_t>(color.w * 255);
40+
41+
return result;
42+
}
43+
44+
static void OnConfigurationChanged() {
45+
Color_RGBA8 c1 = CVarGetColor(CVAR("lCustomRainbow1"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][0]));
46+
Color_RGBA8 c2 = CVarGetColor(CVAR("lCustomRainbow2"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][1]));
47+
Color_RGBA8 c3 = CVarGetColor(CVAR("lCustomRainbow3"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][2]));
48+
Color_RGBA8 c4 = CVarGetColor(CVAR("lCustomRainbow4"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][3]));
49+
50+
customColorZero = Color_LUSToImGui((Color_RGBA8)c1);
51+
customColorOne = Color_LUSToImGui((Color_RGBA8)c2);
52+
customColorMinusZero = Color_LUSToImGui((Color_RGBA8)c3);
53+
customColorMinusOne = Color_LUSToImGui((Color_RGBA8)c4);
54+
55+
// TODO: Register any hooks or things that need to run on startup and when the main CVar is toggled
56+
// Note: Hooks should be registered/unregistered depending on the CVar state (Use COND_HOOK or COND_ID_HOOK)
57+
58+
// COND_HOOK(OnSceneSpawnActors, CVarGetInteger(CVAR("Enabled"), 0), []() {
59+
// // Spawn your own actors?
60+
// });
61+
62+
// COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TSUBO, CVarGetInteger(CVAR("DoSomethingWithPots"), 0), [](void* actorRef) {
63+
// // Do something with pots?
64+
// });
65+
}
66+
67+
static void DrawMenu() {
68+
ImGui::SeparatorText(AUTHOR);
69+
if (ImGui::BeginMenu("Customize Rainbows")) {
70+
UIWidgets::EnhancementCheckbox("Enable", CVAR("lEnableCustomRainbows"));
71+
if (CVarGetInteger(CVAR("lEnableCustomRainbows"), 0)) {
72+
ImGui::ColorEdit3("Color 1", (float*)&customColorZero, ImGuiColorEditFlags_NoInputs);
73+
ImGui::ColorEdit3("Color 2", (float*)&customColorOne, ImGuiColorEditFlags_NoInputs);
74+
ImGui::ColorEdit3("Color 3", (float*)&customColorMinusZero, ImGuiColorEditFlags_NoInputs);
75+
ImGui::ColorEdit3("Color 4", (float*)&customColorMinusOne, ImGuiColorEditFlags_NoInputs);
76+
77+
UIWidgets::PaddedText("Presets", true, false);
78+
size_t rainbowPresetIdx = 0;
79+
if (UIWidgets::EnhancementCombobox(CVAR("lCustomRainbowPreset"), RAINBOW_PRESET_NAMES, 0) &&
80+
(rainbowPresetIdx = CVarGetInteger(CVAR("lCustomRainbowPreset"), 0)) <= RAINBOW_PRESET_LEN) { //paranoia
81+
customColorZero = RAINBOW_PRESETS[rainbowPresetIdx][0];
82+
customColorOne = RAINBOW_PRESETS[rainbowPresetIdx][1];
83+
customColorMinusZero = RAINBOW_PRESETS[rainbowPresetIdx][2];
84+
customColorMinusOne = RAINBOW_PRESETS[rainbowPresetIdx][3];
85+
}
86+
87+
Color_RGBA8 color1, color2, color3, color4;
88+
color1.r = static_cast<uint8_t>(customColorZero.x * 255.0f);
89+
color1.g = static_cast<uint8_t>(customColorZero.y * 255.0f);
90+
color1.b = static_cast<uint8_t>(customColorZero.z * 255.0f);
91+
92+
color2.r = static_cast<uint8_t>(customColorOne.x * 255.0f);
93+
color2.g = static_cast<uint8_t>(customColorOne.y * 255.0f);
94+
color2.b = static_cast<uint8_t>(customColorOne.z * 255.0f);
95+
96+
color3.r = static_cast<uint8_t>(customColorMinusZero.x * 255.0f);
97+
color3.g = static_cast<uint8_t>(customColorMinusZero.y * 255.0f);
98+
color3.b = static_cast<uint8_t>(customColorMinusZero.z * 255.0f);
99+
100+
color4.r = static_cast<uint8_t>(customColorMinusOne.x * 255.0f);
101+
color4.g = static_cast<uint8_t>(customColorMinusOne.y * 255.0f);
102+
color4.b = static_cast<uint8_t>(customColorMinusOne.z * 255.0f);
103+
104+
CVarSetColor(CVAR("lCustomRainbow1"), color1);
105+
CVarSetColor(CVAR("lCustomRainbow2"), color2);
106+
CVarSetColor(CVAR("lCustomRainbow3"), color3);
107+
CVarSetColor(CVAR("lCustomRainbow4"), color4);
108+
109+
OnConfigurationChanged();
110+
}
111+
112+
ImGui::EndMenu();
113+
114+
}
115+
//if (UIWidgets::EnhancementCheckbox("DoSomethingWithPots", CVAR("DoSomethingWithPots"))) {
116+
// OnConfigurationChanged();
117+
//}
118+
}
119+
120+
static void RegisterMod() {
121+
// #region Leave this alone unless you know what you are doing
122+
OnConfigurationChanged();
123+
// #endregion
124+
125+
// TODO: Anything you want to run once on startup
126+
}
127+
128+
// TODO: Uncomment this line to enable the mod
129+
static Holiday holiday(DrawMenu, RegisterMod);

soh/soh/Enhancements/Holiday/LL.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#ifndef LL_H
2+
#define LL_H
3+
4+
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
5+
#include "soh/Enhancements/game-interactor/GameInteractor.h"
6+
7+
const size_t RAINBOW_PRESET_LEN = 9;
8+
9+
static const char* RAINBOW_PRESET_NAMES[RAINBOW_PRESET_LEN] = {
10+
"Christmas",
11+
"Transgender",
12+
"Nonbinary",
13+
"Bisexual",
14+
"Lesbian",
15+
"Gay (MLM)",
16+
"Asexual",
17+
"Brazil",
18+
"Italy"
19+
};
20+
21+
static const ImVec4 RAINBOW_PRESETS[RAINBOW_PRESET_LEN][4] = {
22+
{ //christmas
23+
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
24+
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0},
25+
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
26+
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0}
27+
},
28+
{ //trans
29+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
30+
{255.0/255.0, 159.0/255.0, 186.0/255.0, 0},
31+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
32+
{71.0/255.0, 186.0/255.0, 230.0/255.0, 0}
33+
},
34+
35+
{ //enby
36+
{252.0/255.0, 244.0/255.0, 52.0/255.0, 0},
37+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
38+
{156.0/255.0, 89.0/255.0, 209.0/255.0, 0},
39+
{0.0/255.0, 0.0/255.0, 0.0/255.0, 0}
40+
},
41+
42+
{ //bi
43+
{155.0/255.0, 79.0/255.0, 150.0/255.0, 0},
44+
{0.0/255.0, 56.0/255.0, 168.0/255.0, 0},
45+
{155.0/255.0, 79.0/255.0, 150.0/255.0, 0},
46+
{214.0/255.0, 2.0/255.0, 112.0/255.0, 0}
47+
},
48+
49+
{ //lesbian
50+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
51+
{213.0/255.0, 45.0/255.0, 0.0/255.0, 0},
52+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
53+
{163.0/255.0, 2.0/255.0, 98.0/255.0, 0}
54+
},
55+
56+
{ //gay
57+
{7.0/255.0, 141.0/255.0, 112.0/255.0, 0},
58+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
59+
{123.0/255.0, 173.0/255.0, 226.0/255.0, 0},
60+
{61.0/255.0, 26.0/255.0, 120.0/255.0, 0}
61+
},
62+
63+
{ //ace
64+
{0.0/255.0, 0.0/255.0, 0.0/255.0, 0},
65+
{163.0/255.0, 163.0/255.0, 163.0/255.0, 0},
66+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
67+
{128.0/255.0, 0.0/255.0, 128.0/255.0, 0}
68+
},
69+
70+
{ //br
71+
{0.0/255.0, 151.0/255.0, 57.0/255.0, 0},
72+
{254.0/255.0, 221.0/255.0, 0.0/255.0, 0},
73+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
74+
{1.0/255.0, 33.0/255.0, 105.0/255.0, 0}
75+
},
76+
77+
{ //it
78+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
79+
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
80+
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
81+
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0}
82+
}
83+
84+
};
85+
86+
#endif

soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,8 @@ void ResetPositionAll() {
493493

494494
int hue = 0;
495495

496+
#define CVAR_LL(v) "gHoliday." "LL" "." v
497+
496498
// Runs every frame to update rainbow hue, a potential future optimization is to only run this a once or twice a second and increase the speed of the rainbow hue rotation.
497499
void CosmeticsUpdateTick() {
498500
int index = 0;
@@ -501,10 +503,44 @@ void CosmeticsUpdateTick() {
501503
if (cosmeticOption.supportsRainbow && CVarGetInteger(cosmeticOption.rainbowCvar, 0)) {
502504
double frequency = 2 * M_PI / (360 * rainbowSpeed);
503505
Color_RGBA8 newColor;
504-
newColor.r = static_cast<uint8_t>(sin(frequency * (hue + index) + 0) * 127) + 128;
505-
newColor.g = static_cast<uint8_t>(sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127) + 128;
506-
newColor.b = static_cast<uint8_t>(sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127) + 128;
506+
507507
newColor.a = 255;
508+
509+
if (!CVarGetInteger(CVAR_LL("lEnableCustomRainbows"), 0)) {
510+
newColor.r = static_cast<uint8_t>(sin(frequency * (hue + index) + 0) * 127) + 128;
511+
newColor.g = static_cast<uint8_t>(sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127) + 128;
512+
newColor.b = static_cast<uint8_t>(sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127) + 128;
513+
}
514+
else {
515+
Color_RGBA8 customColorZero = CVarGetColor(CVAR_LL("lCustomRainbow1"), {});
516+
Color_RGBA8 customColorOne = CVarGetColor(CVAR_LL("lCustomRainbow2"), {});
517+
Color_RGBA8 customColorMinusZero = CVarGetColor(CVAR_LL("lCustomRainbow3"), {});
518+
Color_RGBA8 customColorMinusOne = CVarGetColor(CVAR_LL("lCustomRainbow4"), {});
519+
float sinangle = sin(frequency * (hue + index));
520+
bool quadrant1 = hue <= (360 * rainbowSpeed) / 4;
521+
bool quadrant2 = hue >= (360 * rainbowSpeed) / 4 && hue <= (360 * rainbowSpeed) / 2;
522+
bool quadrant3 = hue >= (360 * rainbowSpeed) / 2 && hue <= (360 * rainbowSpeed) * 3 / 4;
523+
bool quadrant4 = hue >= (360 * rainbowSpeed) * 3 / 4;
524+
525+
if (quadrant1) { //zero to one
526+
newColor.r = sinangle * (customColorOne.r - customColorZero.r) + customColorZero.r;
527+
newColor.g = sinangle * (customColorOne.g - customColorZero.g) + customColorZero.g;
528+
newColor.b = sinangle * (customColorOne.b - customColorZero.b) + customColorZero.b;
529+
} else if (quadrant2) { //one to zero
530+
newColor.r = sinangle * (customColorOne.r - customColorMinusZero.r) + customColorMinusZero.r;
531+
newColor.g = sinangle * (customColorOne.g - customColorMinusZero.g) + customColorMinusZero.g;
532+
newColor.b = sinangle * (customColorOne.b - customColorMinusZero.b) + customColorMinusZero.b;
533+
} else if (quadrant3) { //zero to minus one
534+
newColor.r = -sinangle * (customColorMinusOne.r - customColorMinusZero.r) + customColorMinusZero.r;
535+
newColor.g = -sinangle * (customColorMinusOne.g - customColorMinusZero.g) + customColorMinusZero.g;
536+
newColor.b = -sinangle * (customColorMinusOne.b - customColorMinusZero.b) + customColorMinusZero.b;
537+
} else if (quadrant4) { //minus one to zero
538+
newColor.r = -sinangle * (customColorMinusOne.r - customColorZero.r) + customColorZero.r;
539+
newColor.g = -sinangle * (customColorMinusOne.g - customColorZero.g) + customColorZero.g;
540+
newColor.b = -sinangle * (customColorMinusOne.b - customColorZero.b) + customColorZero.b;
541+
}
542+
}
543+
508544
// For alpha supported options, retain the last set alpha instead of overwriting
509545
if (cosmeticOption.supportsAlpha) {
510546
newColor.a = static_cast<uint8_t>(cosmeticOption.currentColor.w * 255.0f);

0 commit comments

Comments
 (0)