Built-in Plandomizer Editor (#4532)

* Add Plandomizer Editor Window

* UI, Ice Trap Editor, Hint Editor

* Drop down for previous seeds, wip hash display.

* Clean Up, Hash Icon Editor

* Updates based on suggestions

* Replace Tint with Color

* Add Boss Soul Icon

* Corrected App Folder Directory and updated from suggesstions.

* Add Hints to Junk Pool

* Utilize RandomElement for hints

* Hint update for pep

* apply patch

* Fix Sorting issue on Linux

* Skeleton Key, Shop Items, Milk, Fishing Pole, Ocarina Buttons, Loser Rupee fixed

* Fix stretched note icons.

* Remove Triforce, add Triforce Pieces. Centered Song Notes.

* Update soh/soh/Enhancements/randomizer/Plandomizer.cpp

Co-authored-by: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com>

* Update hint_list.cpp

One spelling, removed 1 hint.

* Update Plandomizer.cpp

---------

Co-authored-by: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com>
Co-authored-by: Malkierian <malkierian@live.com>
This commit is contained in:
Caladius 2024-11-17 14:44:54 -05:00 committed by GitHub
parent 53e2fe4974
commit 70f3dfa8c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1376 additions and 23 deletions

View File

@ -20,6 +20,10 @@ static const std::unordered_map<std::string, std::string> percentColors = { { "w
{ "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK },
{ "y", QM_YELLOW }, { "B", QM_BLACK } };
static const std::unordered_map<std::string, std::string> colorToPercent = { { QM_WHITE, "%w" }, { QM_RED, "%r"}, { QM_GREEN, "%g" },
{ QM_BLUE, "%b" }, { QM_LBLUE, "%c"}, { QM_PINK, "%p" },
{ QM_YELLOW, "%y" }, { QM_BLACK, "%B" } };
static const std::unordered_map<std::string, ItemID> altarIcons = {
{ "0", ITEM_KOKIRI_EMERALD },
{ "1", ITEM_GORON_RUBY },
@ -147,6 +151,8 @@ void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format)
CleanString(str);
} else if (format == MF_AUTO_FORMAT){
AutoFormatString(str);
}else if (format == MF_ENCODE){
EncodeColors(str);
}
}
@ -281,6 +287,12 @@ void CustomMessage::Clean() {
}
}
void CustomMessage::Encode() {
for (std::string& str : messages) {
EncodeColors(str);
}
}
void CustomMessage::FormatString(std::string& str) const {
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
@ -506,7 +518,23 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) {
return textChar;
}
void CustomMessage::EncodeColors(std::string& str) const {
for (std::string color: colors) {
if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) {
str.replace(firstHashtag, 1, colorToPercent.at(color));
if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) {
str.replace(secondHashtag, 1, "%w");
} else {
SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str);
}
}
}
// Remove any remaining '#' characters.
std::erase(str, '#');
}
void CustomMessage::ReplaceColors(std::string& str) const {
EncodeColors(str);
for (const auto& colorPair : percentColors) {
std::string textToReplace = "%";
textToReplace += colorPair.first;
@ -516,18 +544,6 @@ void CustomMessage::ReplaceColors(std::string& str) const {
start_pos += textToReplace.length();
}
}
for (auto color: colors) {
if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) {
str.replace(firstHashtag, 1, COLOR(color));
if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) {
str.replace(secondHashtag, 1, COLOR(QM_WHITE));
} else {
SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str);
}
}
}
// Remove any remaining '#' characters.
std::erase(str, '#');
}
void CustomMessage::ReplaceAltarIcons(std::string& str) const {
@ -619,6 +635,8 @@ CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_
message.AutoFormat();
} else if (format == MF_CLEAN){
message.Clean();
} else if (format == MF_ENCODE){
message.Encode();
}
return message;

View File

@ -26,7 +26,8 @@ typedef enum {
MF_FORMATTED,
MF_CLEAN,
MF_RAW,
MF_AUTO_FORMAT
MF_AUTO_FORMAT,
MF_ENCODE,
} MessageFormat;
/**
@ -108,6 +109,11 @@ class CustomMessage {
*/
void ReplaceSpecialCharacters(std::string& str) const;
/**
* @brief Replaces hashtags with stored colors.
*/
void EncodeColors(std::string& str) const;
/**
* @brief Replaces our color variable strings with the OoT control codes.
*/
@ -160,6 +166,11 @@ class CustomMessage {
*/
void Clean();
/**
* @brief Replaces variable characters with fixed ones to store the sata in string form
*/
void Encode();
/**
* @brief Replaces various symbols with the control codes necessary to
* display them in OoT's textboxes for a single string

View File

@ -1206,7 +1206,7 @@ void DrawQuestStatusTab() {
ImGui::SameLine();
DrawQuestItemButton(QUEST_GERUDO_CARD);
for (const SongMapEntry& entry : songMapping) {
for (const auto& [quest, entry] : songMapping) {
if ((entry.id != QUEST_SONG_MINUET) && (entry.id != QUEST_SONG_LULLABY)) {
ImGui::SameLine();
}

View File

@ -2253,6 +2253,118 @@ void StaticData::HintTable_Init() {
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_1] = HintText(CustomMessage("They say that %gGanondorf's Mom%w is going out with %ySqueak%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_2] = HintText(CustomMessage("They say that %gProxySaw%w is still fixing %yCaladius's Bugs%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_3] = HintText(CustomMessage("They say that %gItsHeckinPat%w is still just %yEyeballing it%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_4] = HintText(CustomMessage("They say that %gCaladius%w is working on %yV2%w of something.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_5] = HintText(CustomMessage("They say that %gdice%w is a funny name for a %ytaco%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_6] = HintText(CustomMessage("They say %g2Ship Rando%w is still blocked by %yV3%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_7] = HintText(CustomMessage("They say if you click your heels and say %gframebuffer%w 3 times, %yArchez%w appears!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_8] = HintText(CustomMessage("They say %gVB%w stands for %yVirtual Bananas%w... Probably.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_9] = HintText(CustomMessage("They say %gZeru%w is still routing his %yHundo%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_10] = HintText(CustomMessage("They say %gRaccoonCloud%w is still looking for his %yHover Boots%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_11] = HintText(CustomMessage("They say %gItsHeckinPat%w foreclosed on his %yHut%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_12] = HintText(CustomMessage("They say %gRaccoonCloud%w is part of the %yInner Circle%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_13] = HintText(CustomMessage("They say %gMoonlitxShadows%w is the %rleader%w of the %yDork Army%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_14] = HintText(CustomMessage("They say %gGanondorf%w hates the %yInternet%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_15] = HintText(CustomMessage("They say %gMido's House%w hoards %yTrash%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_16] = HintText(CustomMessage("They say %gSweettalking Ganondorf%w rewards %yHis Heart%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_17] = HintText(CustomMessage("They say %gaMannus%w said %yGo To Bed%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_18] = HintText(CustomMessage("They say %gCaladius%w is a %yPinhead%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_19] = HintText(CustomMessage("They say %gRaccoonCloud%w loves the %yIce Cavern%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_20] = HintText(CustomMessage("They say %gNo One%w should forget %yHover Scrub%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_21] = HintText(CustomMessage("They say %gMoonlitxShadows%w likes to %ySlide%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_23] = HintText(CustomMessage("They say that %gBackwalking%w should be %rBanned%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_24] = HintText(CustomMessage("They say that %gGorons%w should always have %yLong Necks%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_25] = HintText(CustomMessage("They say that %gCaladius%w has a %ytendency to lose his shirt%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_26] = HintText(CustomMessage("They say that if your %rSkip keeps Failing%w, you're probably an %yESS Off%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_27] = HintText(CustomMessage("They say that %gLogic%w is just a %ySuggestion%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_28] = HintText(CustomMessage("They say there's %gAlways Logic%w in %yNo Logic%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_29] = HintText(CustomMessage("They said that %rFredomato%w has just %yone more push up%w to do!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
/*--------------------------
| DUNGEON HINT TEXT |
---------------------------*/

View File

@ -113,8 +113,8 @@ StaticHintInfo::StaticHintInfo(HintType _type, std::vector<RandomizerHintTextKey
RandomizerHintTextKey GetRandomJunkHint(){
//temp code to handle random junk hints now I work in keys instead of a vector of HintText
// Will be replaced with a better system once more customisable hint pools are added
uint32_t range = RHT_JUNK_SG_8 - RHT_JUNK02;
//Will be replaced with a better system once more customisable hint pools are added
uint32_t range = RHT_JUNK_CREW_29 - RHT_JUNK02;
return (RandomizerHintTextKey)(Random(0, range) + RHT_JUNK02);
}

View File

@ -69,6 +69,8 @@ struct StaticHintInfo{
std::vector<RandomizerCheck> _hintChecks = {}, bool _yourPocket = false, int _num = 0);
};
RandomizerHintTextKey GetRandomJunkHint();
extern void CreateAllHints();
extern void CreateWarpSongTexts();
void CreateStaticHints();
void CreateStaticHints();
RandomizerHintTextKey GetRandomJunkHint();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
#pragma once
#ifndef PLANDOMIZER_H
#define PLANDOMIZER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // PLANDOMIZER_H
#include <libultraship/libultraship.h>
#include "soh/Enhancements/randomizer/item.h"
#ifdef __cplusplus
class PlandomizerWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;
void InitElement() override;
void DrawElement() override;
void UpdateElement() override{};
};
typedef struct {
std::string checkName;
Rando::Item checkRewardItem;
int32_t shopPrice;
Rando::Item iceTrapModel;
std::string iceTrapName;
} SpoilerCheckObject;
typedef struct {
std::string hintName;
std::string hintType;
std::string hintText;
} SpoilerHintObject;
typedef enum {
TAB_HINTS,
TAB_LOCATIONS
};
typedef enum {
HINT_SINGLE,
HINT_ALL,
};
#endif

View File

@ -10,7 +10,7 @@
#include <textures/icon_item_static/icon_item_static.h>
#include <textures/icon_item_24_static/icon_item_24_static.h>
std::array<Sprite, 100> gSeedTextures = { {
inline std::array<Sprite, 100> gSeedTextures = { {
{ dgItemIconDekuNutTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0 },
{ dgItemIconDekuStickTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 1 },
{ dgItemIconBombTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 2 },

View File

@ -2627,6 +2627,35 @@ typedef enum {
RHT_JUNK_SG_6,
RHT_JUNK_SG_7,
RHT_JUNK_SG_8,
RHT_JUNK_CREW_1,
RHT_JUNK_CREW_2,
RHT_JUNK_CREW_3,
RHT_JUNK_CREW_4,
RHT_JUNK_CREW_5,
RHT_JUNK_CREW_6,
RHT_JUNK_CREW_7,
RHT_JUNK_CREW_8,
RHT_JUNK_CREW_9,
RHT_JUNK_CREW_10,
RHT_JUNK_CREW_11,
RHT_JUNK_CREW_12,
RHT_JUNK_CREW_13,
RHT_JUNK_CREW_14,
RHT_JUNK_CREW_15,
RHT_JUNK_CREW_16,
RHT_JUNK_CREW_17,
RHT_JUNK_CREW_18,
RHT_JUNK_CREW_19,
RHT_JUNK_CREW_20,
RHT_JUNK_CREW_21,
RHT_JUNK_CREW_22,
RHT_JUNK_CREW_23,
RHT_JUNK_CREW_24,
RHT_JUNK_CREW_25,
RHT_JUNK_CREW_26,
RHT_JUNK_CREW_27,
RHT_JUNK_CREW_28,
RHT_JUNK_CREW_29,
// Locations
RHT_LINKS_POCKET,
RHT_QUEEN_GOHMA,

View File

@ -1,6 +1,7 @@
#include "ImGuiUtils.h"
#include <Context.h>
#include "assets/soh_assets.h"
#include "soh/Enhancements/randomizer/rando_hash.h"
std::map<uint32_t, ItemMapEntry> itemMapping = {
ITEM_MAP_ENTRY(ITEM_STICK),
@ -150,7 +151,7 @@ std::map<uint32_t, QuestMapEntry> questMapping = {
QUEST_MAP_ENTRY(QUEST_SKULL_TOKEN, dgQuestIconGoldSkulltulaTex),
};
std::array<SongMapEntry, 12> songMapping = { {
std::map<QuestItem, SongMapEntry> songMapping = {
SONG_MAP_ENTRY(QUEST_SONG_LULLABY, 224, 107, 255),
SONG_MAP_ENTRY(QUEST_SONG_EPONA, 255, 195, 60),
SONG_MAP_ENTRY(QUEST_SONG_SARIA, 127, 255, 137),
@ -163,7 +164,7 @@ std::array<SongMapEntry, 12> songMapping = { {
SONG_MAP_ENTRY(QUEST_SONG_REQUIEM, 255, 160, 0),
SONG_MAP_ENTRY(QUEST_SONG_NOCTURNE, 255, 100, 255),
SONG_MAP_ENTRY(QUEST_SONG_PRELUDE, 255, 240, 100),
} };
};
std::array<SongMapEntry, 12> vanillaSongMapping = { {
VANILLA_SONG_MAP_ENTRY(QUEST_SONG_LULLABY, 255, 255, 255),
@ -212,7 +213,7 @@ void RegisterImGuiItemIcons() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
}
for (const auto& entry : songMapping) {
for (const auto& [quest, entry] : songMapping) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
ImVec4 fadedCol = entry.color;
fadedCol.w = 0.3f;
@ -225,4 +226,8 @@ void RegisterImGuiItemIcons() {
fadedCol.w = 0.3f;
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
}
for (const auto& entry : gSeedTextures) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.tex, entry.tex, ImVec4(1, 1, 1, 1));
}
}

View File

@ -67,11 +67,11 @@ typedef struct {
#define SONG_MAP_ENTRY(id, r, g, b) \
{ \
id, #id, #id "_Faded", ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f) \
id, { id, #id, #id "_Faded", ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f) } \
}
// Maps song ids to info for use in ImGui
extern std::array<SongMapEntry, 12> songMapping;
extern std::map<QuestItem, SongMapEntry> songMapping;
#define VANILLA_SONG_MAP_ENTRY(id, r, g, b) \
{ \

View File

@ -131,6 +131,7 @@ namespace SohGui {
std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
std::shared_ptr<PlandomizerWindow> mPlandomizerWindow;
std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
std::shared_ptr<SohModalWindow> mModalWindow;
@ -210,6 +211,8 @@ namespace SohGui {
gui->AddGuiWindow(mRandomizerSettingsWindow);
mTimeSplitWindow = std::make_shared<TimeSplitWindow>(CVAR_WINDOW("TimeSplitEnabled"), "Time Splits", ImVec2(450, 660));
gui->AddGuiWindow(mTimeSplitWindow);
mPlandomizerWindow = std::make_shared<PlandomizerWindow>(CVAR_WINDOW("PlandomizerWindow"), "Plandomizer Editor", ImVec2(850, 760));
gui->AddGuiWindow(mPlandomizerWindow);
mAdvancedResolutionSettingsWindow = std::make_shared<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow>(CVAR_WINDOW("AdvancedResolutionEditor"), "Advanced Resolution Settings", ImVec2(497, 599));
gui->AddGuiWindow(mAdvancedResolutionSettingsWindow);
mModalWindow = std::make_shared<SohModalWindow>(CVAR_WINDOW("ModalWindow"), "Modal Window");
@ -252,6 +255,7 @@ namespace SohGui {
mInputViewer = nullptr;
mInputViewerSettings = nullptr;
mTimeSplitWindow = nullptr;
mPlandomizerWindow = nullptr;
}
void RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function<void()> button1callback, std::function<void()> button2callback) {

View File

@ -25,6 +25,7 @@
#include "Enhancements/randomizer/randomizer_item_tracker.h"
#include "Enhancements/randomizer/randomizer_settings_window.h"
#include "Enhancements/timesplits/TimeSplits.h"
#include "Enhancements/randomizer/Plandomizer.h"
#include "SohModals.h"
#ifdef __cplusplus

View File

@ -41,6 +41,7 @@
#include "Enhancements/resolution-editor/ResolutionEditor.h"
#include "Enhancements/enemyrandomizer.h"
#include "Enhancements/timesplits/TimeSplits.h"
#include "Enhancements/randomizer/Plandomizer.h"
// FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but
// they don't work how I expect them to so I added that because it looked good when I eyeballed it
@ -2046,6 +2047,7 @@ extern std::shared_ptr<EntranceTrackerWindow> mEntranceTrackerWindow;
extern std::shared_ptr<EntranceTrackerSettingsWindow> mEntranceTrackerSettingsWindow;
extern std::shared_ptr<CheckTracker::CheckTrackerWindow> mCheckTrackerWindow;
extern std::shared_ptr<CheckTracker::CheckTrackerSettingsWindow> mCheckTrackerSettingsWindow;
extern std::shared_ptr<PlandomizerWindow> mPlandomizerWindow;
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
void DrawRandomizerMenu() {
@ -2075,6 +2077,14 @@ void DrawRandomizerMenu() {
static float separationToOptionsButton = 5.0f;
#endif
if (mPlandomizerWindow) {
if (ImGui::Button(GetWindowButtonText("Plandomizer Editor", CVarGetInteger(CVAR_WINDOW("PlandomizerWindow"), 0)).c_str(), buttonSize)) {
mPlandomizerWindow->ToggleVisibility();
}
}
UIWidgets::Spacer(0);
if (mRandomizerSettingsWindow) {
if (ImGui::Button(GetWindowButtonText("Randomizer Settings", CVarGetInteger(CVAR_WINDOW("RandomizerSettings"), 0)).c_str(), buttonSize)) {
mRandomizerSettingsWindow->ToggleVisibility();