[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>
This commit is contained in:
lilacLunatic 2024-12-17 07:35:54 -03:00 committed by GitHub
parent a10b4d0662
commit d725125f9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 254 additions and 3 deletions

View File

@ -0,0 +1,129 @@
#include "Holiday.hpp"
#include "LL.h"
extern "C" {
#include "macros.h"
#include "functions.h"
#include "variables.h"
extern PlayState* gPlayState;
// TODO: Include anything you need here from C land
}
// TODO: Change this to YourName
#define AUTHOR "LL"
#define CVAR(v) "gHoliday." AUTHOR "." v
static ImVec4 customColorZero = RAINBOW_PRESETS[0][0];
static ImVec4 customColorOne = RAINBOW_PRESETS[0][1];
static ImVec4 customColorMinusZero = RAINBOW_PRESETS[0][2];
static ImVec4 customColorMinusOne = RAINBOW_PRESETS[0][3];
ImVec4 Color_LUSToImGui(Color_RGBA8 color) {
ImVec4 result;
result.x = color.r / 255.0f;
result.y = color.g / 255.0f;
result.z = color.b / 255.0f;
result.w = color.a / 255.0f;
return result;
}
Color_RGBA8 Color_ImGuiToLUS(ImVec4 color) {
Color_RGBA8 result;
result.r = static_cast<uint8_t>(color.x * 255);
result.g = static_cast<uint8_t>(color.y * 255);
result.b = static_cast<uint8_t>(color.z * 255);
result.a = static_cast<uint8_t>(color.w * 255);
return result;
}
static void OnConfigurationChanged() {
Color_RGBA8 c1 = CVarGetColor(CVAR("lCustomRainbow1"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][0]));
Color_RGBA8 c2 = CVarGetColor(CVAR("lCustomRainbow2"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][1]));
Color_RGBA8 c3 = CVarGetColor(CVAR("lCustomRainbow3"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][2]));
Color_RGBA8 c4 = CVarGetColor(CVAR("lCustomRainbow4"), Color_ImGuiToLUS(RAINBOW_PRESETS[0][3]));
customColorZero = Color_LUSToImGui((Color_RGBA8)c1);
customColorOne = Color_LUSToImGui((Color_RGBA8)c2);
customColorMinusZero = Color_LUSToImGui((Color_RGBA8)c3);
customColorMinusOne = Color_LUSToImGui((Color_RGBA8)c4);
// TODO: Register any hooks or things that need to run on startup and when the main CVar is toggled
// Note: Hooks should be registered/unregistered depending on the CVar state (Use COND_HOOK or COND_ID_HOOK)
// COND_HOOK(OnSceneSpawnActors, CVarGetInteger(CVAR("Enabled"), 0), []() {
// // Spawn your own actors?
// });
// COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TSUBO, CVarGetInteger(CVAR("DoSomethingWithPots"), 0), [](void* actorRef) {
// // Do something with pots?
// });
}
static void DrawMenu() {
ImGui::SeparatorText(AUTHOR);
if (ImGui::BeginMenu("Customize Rainbows")) {
UIWidgets::EnhancementCheckbox("Enable", CVAR("lEnableCustomRainbows"));
if (CVarGetInteger(CVAR("lEnableCustomRainbows"), 0)) {
ImGui::ColorEdit3("Color 1", (float*)&customColorZero, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit3("Color 2", (float*)&customColorOne, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit3("Color 3", (float*)&customColorMinusZero, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit3("Color 4", (float*)&customColorMinusOne, ImGuiColorEditFlags_NoInputs);
UIWidgets::PaddedText("Presets", true, false);
size_t rainbowPresetIdx = 0;
if (UIWidgets::EnhancementCombobox(CVAR("lCustomRainbowPreset"), RAINBOW_PRESET_NAMES, 0) &&
(rainbowPresetIdx = CVarGetInteger(CVAR("lCustomRainbowPreset"), 0)) <= RAINBOW_PRESET_LEN) { //paranoia
customColorZero = RAINBOW_PRESETS[rainbowPresetIdx][0];
customColorOne = RAINBOW_PRESETS[rainbowPresetIdx][1];
customColorMinusZero = RAINBOW_PRESETS[rainbowPresetIdx][2];
customColorMinusOne = RAINBOW_PRESETS[rainbowPresetIdx][3];
}
Color_RGBA8 color1, color2, color3, color4;
color1.r = static_cast<uint8_t>(customColorZero.x * 255.0f);
color1.g = static_cast<uint8_t>(customColorZero.y * 255.0f);
color1.b = static_cast<uint8_t>(customColorZero.z * 255.0f);
color2.r = static_cast<uint8_t>(customColorOne.x * 255.0f);
color2.g = static_cast<uint8_t>(customColorOne.y * 255.0f);
color2.b = static_cast<uint8_t>(customColorOne.z * 255.0f);
color3.r = static_cast<uint8_t>(customColorMinusZero.x * 255.0f);
color3.g = static_cast<uint8_t>(customColorMinusZero.y * 255.0f);
color3.b = static_cast<uint8_t>(customColorMinusZero.z * 255.0f);
color4.r = static_cast<uint8_t>(customColorMinusOne.x * 255.0f);
color4.g = static_cast<uint8_t>(customColorMinusOne.y * 255.0f);
color4.b = static_cast<uint8_t>(customColorMinusOne.z * 255.0f);
CVarSetColor(CVAR("lCustomRainbow1"), color1);
CVarSetColor(CVAR("lCustomRainbow2"), color2);
CVarSetColor(CVAR("lCustomRainbow3"), color3);
CVarSetColor(CVAR("lCustomRainbow4"), color4);
OnConfigurationChanged();
}
ImGui::EndMenu();
}
//if (UIWidgets::EnhancementCheckbox("DoSomethingWithPots", CVAR("DoSomethingWithPots"))) {
// OnConfigurationChanged();
//}
}
static void RegisterMod() {
// #region Leave this alone unless you know what you are doing
OnConfigurationChanged();
// #endregion
// TODO: Anything you want to run once on startup
}
// TODO: Uncomment this line to enable the mod
static Holiday holiday(DrawMenu, RegisterMod);

View File

@ -0,0 +1,86 @@
#ifndef LL_H
#define LL_H
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
const size_t RAINBOW_PRESET_LEN = 9;
static const char* RAINBOW_PRESET_NAMES[RAINBOW_PRESET_LEN] = {
"Christmas",
"Transgender",
"Nonbinary",
"Bisexual",
"Lesbian",
"Gay (MLM)",
"Asexual",
"Brazil",
"Italy"
};
static const ImVec4 RAINBOW_PRESETS[RAINBOW_PRESET_LEN][4] = {
{ //christmas
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0},
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0}
},
{ //trans
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{255.0/255.0, 159.0/255.0, 186.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{71.0/255.0, 186.0/255.0, 230.0/255.0, 0}
},
{ //enby
{252.0/255.0, 244.0/255.0, 52.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{156.0/255.0, 89.0/255.0, 209.0/255.0, 0},
{0.0/255.0, 0.0/255.0, 0.0/255.0, 0}
},
{ //bi
{155.0/255.0, 79.0/255.0, 150.0/255.0, 0},
{0.0/255.0, 56.0/255.0, 168.0/255.0, 0},
{155.0/255.0, 79.0/255.0, 150.0/255.0, 0},
{214.0/255.0, 2.0/255.0, 112.0/255.0, 0}
},
{ //lesbian
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{213.0/255.0, 45.0/255.0, 0.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{163.0/255.0, 2.0/255.0, 98.0/255.0, 0}
},
{ //gay
{7.0/255.0, 141.0/255.0, 112.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{123.0/255.0, 173.0/255.0, 226.0/255.0, 0},
{61.0/255.0, 26.0/255.0, 120.0/255.0, 0}
},
{ //ace
{0.0/255.0, 0.0/255.0, 0.0/255.0, 0},
{163.0/255.0, 163.0/255.0, 163.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{128.0/255.0, 0.0/255.0, 128.0/255.0, 0}
},
{ //br
{0.0/255.0, 151.0/255.0, 57.0/255.0, 0},
{254.0/255.0, 221.0/255.0, 0.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{1.0/255.0, 33.0/255.0, 105.0/255.0, 0}
},
{ //it
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{0.0/255.0, 140.0/255.0, 69.0/255.0, 0},
{255.0/255.0, 255.0/255.0, 255.0/255.0, 0},
{205.0/255.0, 33.0/255.0, 42.0/255.0, 0}
}
};
#endif

View File

@ -493,6 +493,8 @@ void ResetPositionAll() {
int hue = 0;
#define CVAR_LL(v) "gHoliday." "LL" "." v
// 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.
void CosmeticsUpdateTick() {
int index = 0;
@ -501,10 +503,44 @@ void CosmeticsUpdateTick() {
if (cosmeticOption.supportsRainbow && CVarGetInteger(cosmeticOption.rainbowCvar, 0)) {
double frequency = 2 * M_PI / (360 * rainbowSpeed);
Color_RGBA8 newColor;
newColor.r = static_cast<uint8_t>(sin(frequency * (hue + index) + 0) * 127) + 128;
newColor.g = static_cast<uint8_t>(sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127) + 128;
newColor.b = static_cast<uint8_t>(sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127) + 128;
newColor.a = 255;
if (!CVarGetInteger(CVAR_LL("lEnableCustomRainbows"), 0)) {
newColor.r = static_cast<uint8_t>(sin(frequency * (hue + index) + 0) * 127) + 128;
newColor.g = static_cast<uint8_t>(sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127) + 128;
newColor.b = static_cast<uint8_t>(sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127) + 128;
}
else {
Color_RGBA8 customColorZero = CVarGetColor(CVAR_LL("lCustomRainbow1"), {});
Color_RGBA8 customColorOne = CVarGetColor(CVAR_LL("lCustomRainbow2"), {});
Color_RGBA8 customColorMinusZero = CVarGetColor(CVAR_LL("lCustomRainbow3"), {});
Color_RGBA8 customColorMinusOne = CVarGetColor(CVAR_LL("lCustomRainbow4"), {});
float sinangle = sin(frequency * (hue + index));
bool quadrant1 = hue <= (360 * rainbowSpeed) / 4;
bool quadrant2 = hue >= (360 * rainbowSpeed) / 4 && hue <= (360 * rainbowSpeed) / 2;
bool quadrant3 = hue >= (360 * rainbowSpeed) / 2 && hue <= (360 * rainbowSpeed) * 3 / 4;
bool quadrant4 = hue >= (360 * rainbowSpeed) * 3 / 4;
if (quadrant1) { //zero to one
newColor.r = sinangle * (customColorOne.r - customColorZero.r) + customColorZero.r;
newColor.g = sinangle * (customColorOne.g - customColorZero.g) + customColorZero.g;
newColor.b = sinangle * (customColorOne.b - customColorZero.b) + customColorZero.b;
} else if (quadrant2) { //one to zero
newColor.r = sinangle * (customColorOne.r - customColorMinusZero.r) + customColorMinusZero.r;
newColor.g = sinangle * (customColorOne.g - customColorMinusZero.g) + customColorMinusZero.g;
newColor.b = sinangle * (customColorOne.b - customColorMinusZero.b) + customColorMinusZero.b;
} else if (quadrant3) { //zero to minus one
newColor.r = -sinangle * (customColorMinusOne.r - customColorMinusZero.r) + customColorMinusZero.r;
newColor.g = -sinangle * (customColorMinusOne.g - customColorMinusZero.g) + customColorMinusZero.g;
newColor.b = -sinangle * (customColorMinusOne.b - customColorMinusZero.b) + customColorMinusZero.b;
} else if (quadrant4) { //minus one to zero
newColor.r = -sinangle * (customColorMinusOne.r - customColorZero.r) + customColorZero.r;
newColor.g = -sinangle * (customColorMinusOne.g - customColorZero.g) + customColorZero.g;
newColor.b = -sinangle * (customColorMinusOne.b - customColorZero.b) + customColorZero.b;
}
}
// For alpha supported options, retain the last set alpha instead of overwriting
if (cosmeticOption.supportsAlpha) {
newColor.a = static_cast<uint8_t>(cosmeticOption.currentColor.w * 255.0f);