From 16bf03a9bda21aa4f96ceb0e2596d24961f0cc3b Mon Sep 17 00:00:00 2001
From: Ted Newman <Tawling@users.noreply.github.com>
Date: Sat, 20 Apr 2024 08:33:59 -0800
Subject: [PATCH] Add console commands for randomizing sfx and cosmetic groups
 (#3962)

* Add console commands for randomizing sfx and cosmetic groups

* Update naming and use constexpr

* Update soh/soh/Enhancements/debugconsole.cpp

---------

Co-authored-by: Archez <Archez@users.noreply.github.com>
---
 soh/soh/Enhancements/audio/AudioCollection.h  |   1 +
 soh/soh/Enhancements/audio/AudioEditor.cpp    |  14 +
 soh/soh/Enhancements/audio/AudioEditor.h      |   3 +
 .../cosmetics/CosmeticsEditor.cpp             | 416 +++++++++---------
 .../Enhancements/cosmetics/CosmeticsEditor.h  |  25 ++
 soh/soh/Enhancements/debugconsole.cpp         |  86 +++-
 soh/soh/SohMenuBar.cpp                        |  16 +-
 7 files changed, 338 insertions(+), 223 deletions(-)

diff --git a/soh/soh/Enhancements/audio/AudioCollection.h b/soh/soh/Enhancements/audio/AudioCollection.h
index 1d53777e7..f3fd964bc 100644
--- a/soh/soh/Enhancements/audio/AudioCollection.h
+++ b/soh/soh/Enhancements/audio/AudioCollection.h
@@ -1,3 +1,4 @@
+#pragma once
 #ifdef __cplusplus
 #include <map>
 #include <string>
diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp
index 8c0d415a3..68077a968 100644
--- a/soh/soh/Enhancements/audio/AudioEditor.cpp
+++ b/soh/soh/Enhancements/audio/AudioEditor.cpp
@@ -714,6 +714,13 @@ void AudioEditor_RandomizeAll() {
     ReplayCurrentBGM();
 }
 
+void AudioEditor_RandomizeGroup(SeqType group) {
+    RandomizeGroup(group);
+
+    LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
+    ReplayCurrentBGM();
+}
+
 void AudioEditor_ResetAll() {
     for (auto type : allTypes) {
         ResetGroup(AudioCollection::Instance->GetAllSequences(), type);
@@ -723,6 +730,13 @@ void AudioEditor_ResetAll() {
     ReplayCurrentBGM();
 }
 
+void AudioEditor_ResetGroup(SeqType group) {
+    ResetGroup(AudioCollection::Instance->GetAllSequences(), group);
+
+    LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
+    ReplayCurrentBGM();
+}
+
 void AudioEditor_LockAll() {
     for (auto type : allTypes) {
         LockGroup(AudioCollection::Instance->GetAllSequences(), type);
diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h
index 9cca94efe..38a681539 100644
--- a/soh/soh/Enhancements/audio/AudioEditor.h
+++ b/soh/soh/Enhancements/audio/AudioEditor.h
@@ -8,6 +8,7 @@
 #define IMGUI_DEFINE_MATH_OPERATORS
 #endif
 #include <ImGui/imgui.h>
+#include "AudioCollection.h"
 
 class AudioEditor : public LUS::GuiWindow {
     public:
@@ -20,7 +21,9 @@ class AudioEditor : public LUS::GuiWindow {
 };
 
 void AudioEditor_RandomizeAll();
+void AudioEditor_RandomizeGroup(SeqType group);
 void AudioEditor_ResetAll();
+void AudioEditor_ResetGroup(SeqType group);
 void AudioEditor_LockAll();
 void AudioEditor_UnlockAll();
 
diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
index 4f04bc64b..52f319b3e 100644
--- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
+++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
@@ -57,46 +57,24 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
 #define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL"
 static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL;
 
-// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
-// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
-typedef enum {
-    GROUP_LINK,
-    GROUP_MIRRORSHIELD,
-    GROUP_SWORDS,
-    GROUP_GLOVES,
-    GROUP_EQUIPMENT,
-    GROUP_CONSUMABLE,
-    GROUP_HUD,
-    GROUP_KALEIDO,
-    GROUP_TITLE,
-    GROUP_NPC,
-    GROUP_WORLD,
-    GROUP_MAGIC,
-    GROUP_ARROWS,
-    GROUP_SPIN_ATTACK,
-    GROUP_TRAILS,
-    GROUP_NAVI,
-    GROUP_IVAN,
-} CosmeticGroup;
-
 std::map<CosmeticGroup, const char*> groupLabels = {
-    { GROUP_LINK, "Link" },
-    { GROUP_MIRRORSHIELD, "Mirror Shield" },
-    { GROUP_SWORDS, "Swords" },
-    { GROUP_GLOVES, "Gloves" },
-    { GROUP_EQUIPMENT, "Equipment" },
-    { GROUP_CONSUMABLE, "Consumables" },
-    { GROUP_HUD, "HUD" },
-    { GROUP_KALEIDO, "Pause Menu" },
-    { GROUP_TITLE, "Title Screen" },
-    { GROUP_NPC, "NPCs" },
-    { GROUP_WORLD, "World" },
-    { GROUP_MAGIC, "Magic Effects" },
-    { GROUP_ARROWS, "Arrow Effects" },
-    { GROUP_SPIN_ATTACK, "Spin Attack" },
-    { GROUP_TRAILS, "Trails" },
-    { GROUP_NAVI, "Navi" },
-    { GROUP_IVAN, "Ivan" } 
+    { COSMETICS_GROUP_LINK, "Link" },
+    { COSMETICS_GROUP_MIRRORSHIELD, "Mirror Shield" },
+    { COSMETICS_GROUP_SWORDS, "Swords" },
+    { COSMETICS_GROUP_GLOVES, "Gloves" },
+    { COSMETICS_GROUP_EQUIPMENT, "Equipment" },
+    { COSMETICS_GROUP_CONSUMABLE, "Consumables" },
+    { COSMETICS_GROUP_HUD, "HUD" },
+    { COSMETICS_GROUP_KALEIDO, "Pause Menu" },
+    { COSMETICS_GROUP_TITLE, "Title Screen" },
+    { COSMETICS_GROUP_NPC, "NPCs" },
+    { COSMETICS_GROUP_WORLD, "World" },
+    { COSMETICS_GROUP_MAGIC, "Magic Effects" },
+    { COSMETICS_GROUP_ARROWS, "Arrow Effects" },
+    { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" },
+    { COSMETICS_GROUP_TRAILS, "Trails" },
+    { COSMETICS_GROUP_NAVI, "Navi" },
+    { COSMETICS_GROUP_IVAN, "Ivan" } 
 };
 
 typedef struct {
@@ -194,180 +172,180 @@ typedef struct {
     colors were darker than the gDPSetPrimColor. You will see many more examples of this below in the `ApplyOrResetCustomGfxPatches` method
 */
 static std::map<std::string, CosmeticOption> cosmeticOptions = {
-    COSMETIC_OPTION("Link_KokiriTunic",              "Kokiri Tunic",         GROUP_LINK,         ImVec4( 30, 105,  27, 255), false, true, false),
-    COSMETIC_OPTION("Link_GoronTunic",               "Goron Tunic",          GROUP_LINK,         ImVec4(100,  20,   0, 255), false, true, false),
-    COSMETIC_OPTION("Link_ZoraTunic",                "Zora Tunic",           GROUP_LINK,         ImVec4(  0,  60, 100, 255), false, true, false),
-    COSMETIC_OPTION("Link_Hair",                     "Hair",                 GROUP_LINK,         ImVec4(255, 173,  27, 255), false, true, true),
-    COSMETIC_OPTION("Link_Linen",                    "Linen",                GROUP_LINK,         ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Link_Boots",                    "Boots",                GROUP_LINK,         ImVec4( 93,  44,  18, 255), false, true, true),
+    COSMETIC_OPTION("Link_KokiriTunic",              "Kokiri Tunic",         COSMETICS_GROUP_LINK,         ImVec4( 30, 105,  27, 255), false, true, false),
+    COSMETIC_OPTION("Link_GoronTunic",               "Goron Tunic",          COSMETICS_GROUP_LINK,         ImVec4(100,  20,   0, 255), false, true, false),
+    COSMETIC_OPTION("Link_ZoraTunic",                "Zora Tunic",           COSMETICS_GROUP_LINK,         ImVec4(  0,  60, 100, 255), false, true, false),
+    COSMETIC_OPTION("Link_Hair",                     "Hair",                 COSMETICS_GROUP_LINK,         ImVec4(255, 173,  27, 255), false, true, true),
+    COSMETIC_OPTION("Link_Linen",                    "Linen",                COSMETICS_GROUP_LINK,         ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Link_Boots",                    "Boots",                COSMETICS_GROUP_LINK,         ImVec4( 93,  44,  18, 255), false, true, true),
     
-    COSMETIC_OPTION("MirrorShield_Body",             "Body",                 GROUP_MIRRORSHIELD, ImVec4(215,   0,   0, 255), false, true, false),
-    COSMETIC_OPTION("MirrorShield_Mirror",           "Mirror",               GROUP_MIRRORSHIELD, ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("MirrorShield_Emblem",           "Emblem",               GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true),
+    COSMETIC_OPTION("MirrorShield_Body",             "Body",                 COSMETICS_GROUP_MIRRORSHIELD, ImVec4(215,   0,   0, 255), false, true, false),
+    COSMETIC_OPTION("MirrorShield_Mirror",           "Mirror",               COSMETICS_GROUP_MIRRORSHIELD, ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("MirrorShield_Emblem",           "Emblem",               COSMETICS_GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true),
 
-    COSMETIC_OPTION("Swords_KokiriBlade",            "Kokiri Sword Blade",   GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
-    // COSMETIC_OPTION("Swords_KokiriHilt",             "Kokiri Sword Hilt",    GROUP_SWORDS,       ImVec4(160, 100,  15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
-    COSMETIC_OPTION("Swords_MasterBlade",            "Master Sword Blade",   GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
-    // COSMETIC_OPTION("Swords_MasterHilt",             "Master Sword Hilt",    GROUP_SWORDS,       ImVec4( 80,  80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
-    COSMETIC_OPTION("Swords_BiggoronBlade",          "Biggoron Sword Blade", GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
-    // COSMETIC_OPTION("Swords_BiggoronHilt",           "Biggoron Sword Hilt",  GROUP_SWORDS,       ImVec4( 80,  80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
+    COSMETIC_OPTION("Swords_KokiriBlade",            "Kokiri Sword Blade",   COSMETICS_GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
+    // COSMETIC_OPTION("Swords_KokiriHilt",             "Kokiri Sword Hilt",    COSMETICS_GROUP_SWORDS,       ImVec4(160, 100,  15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
+    COSMETIC_OPTION("Swords_MasterBlade",            "Master Sword Blade",   COSMETICS_GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
+    // COSMETIC_OPTION("Swords_MasterHilt",             "Master Sword Hilt",    COSMETICS_GROUP_SWORDS,       ImVec4( 80,  80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
+    COSMETIC_OPTION("Swords_BiggoronBlade",          "Biggoron Sword Blade", COSMETICS_GROUP_SWORDS,       ImVec4(255, 255, 255, 255), false, true, false),
+    // COSMETIC_OPTION("Swords_BiggoronHilt",           "Biggoron Sword Hilt",  COSMETICS_GROUP_SWORDS,       ImVec4( 80,  80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
 
-    COSMETIC_OPTION("Gloves_GoronBracelet",          "Goron Bracelet",       GROUP_GLOVES,       ImVec4(255, 255, 170, 255), false, true, false),
-    COSMETIC_OPTION("Gloves_SilverGauntlets",        "Silver Gauntlets",     GROUP_GLOVES,       ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Gloves_GoldenGauntlets",        "Golden Gauntlets",     GROUP_GLOVES,       ImVec4(254, 207,  15, 255), false, true, false),
-    COSMETIC_OPTION("Gloves_GauntletsGem",           "Gauntlets Gem",        GROUP_GLOVES,       ImVec4(255,  60, 100, 255), false, true, true),
+    COSMETIC_OPTION("Gloves_GoronBracelet",          "Goron Bracelet",       COSMETICS_GROUP_GLOVES,       ImVec4(255, 255, 170, 255), false, true, false),
+    COSMETIC_OPTION("Gloves_SilverGauntlets",        "Silver Gauntlets",     COSMETICS_GROUP_GLOVES,       ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Gloves_GoldenGauntlets",        "Golden Gauntlets",     COSMETICS_GROUP_GLOVES,       ImVec4(254, 207,  15, 255), false, true, false),
+    COSMETIC_OPTION("Gloves_GauntletsGem",           "Gauntlets Gem",        COSMETICS_GROUP_GLOVES,       ImVec4(255,  60, 100, 255), false, true, true),
     
-    COSMETIC_OPTION("Equipment_BoomerangBody",       "Boomerang Body",       GROUP_EQUIPMENT,    ImVec4(160, 100,   0, 255), false, true, false),
-    COSMETIC_OPTION("Equipment_BoomerangGem",        "Boomerang Gem",        GROUP_EQUIPMENT,    ImVec4(255,  50, 150, 255), false, true, true),
-    // COSMETIC_OPTION("Equipment_SlingshotBody",       "Slingshot Body",       GROUP_EQUIPMENT,    ImVec4(160, 100,   0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
-    COSMETIC_OPTION("Equipment_SlingshotString",     "Slingshot String",     GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Equipment_HammerHead",          "Hammer Head",          GROUP_EQUIPMENT,    ImVec4(155, 192, 201, 255), false, true, false),
-    COSMETIC_OPTION("Equipment_HammerHandle",        "Hammer Handle",        GROUP_EQUIPMENT,    ImVec4(110,  60,   0, 255), false, true, true),
-    // COSMETIC_OPTION("Equipment_HookshotChain",       "Hookshot Chain",       GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement
-    // COSMETIC_OPTION("Equipment_HookshotTip",         "Hookshot Tip",         GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement
-    COSMETIC_OPTION("HookshotReticle_Target",        "Hookshotable Reticle", GROUP_EQUIPMENT,         ImVec4(  0, 255,   0, 255), false, false, false),
-    COSMETIC_OPTION("HookshotReticle_NonTarget",     "Non-Hookshotable Reticle", GROUP_EQUIPMENT,     ImVec4(255,   0,   0, 255), false, false, false),
-    COSMETIC_OPTION("Equipment_BowTips",             "Bow Tips",             GROUP_EQUIPMENT,    ImVec4(200,   0,   0, 255), false, true, true),
-    COSMETIC_OPTION("Equipment_BowString",           "Bow String",           GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Equipment_BowBody",             "Bow Body",             GROUP_EQUIPMENT,    ImVec4(140,  90,  10, 255), false, true, false),
-    COSMETIC_OPTION("Equipment_BowHandle",           "Bow Handle",           GROUP_EQUIPMENT,    ImVec4( 50, 150, 255, 255), false, true, true),
-    COSMETIC_OPTION("Equipment_ChuFace",             "Bombchu Face",         GROUP_EQUIPMENT,    ImVec4(  0, 100, 150, 255), false, true, true),
-    COSMETIC_OPTION("Equipment_ChuBody",             "Bombchu Body",         GROUP_EQUIPMENT,    ImVec4(180, 130,  50, 255), false, true, true), 
-    COSMETIC_OPTION("Equipment_BunnyHood",           "Bunny Hood",           GROUP_EQUIPMENT,    ImVec4(255, 235,  109, 255), false, true, true), 
+    COSMETIC_OPTION("Equipment_BoomerangBody",       "Boomerang Body",       COSMETICS_GROUP_EQUIPMENT,    ImVec4(160, 100,   0, 255), false, true, false),
+    COSMETIC_OPTION("Equipment_BoomerangGem",        "Boomerang Gem",        COSMETICS_GROUP_EQUIPMENT,    ImVec4(255,  50, 150, 255), false, true, true),
+    // COSMETIC_OPTION("Equipment_SlingshotBody",       "Slingshot Body",       COSMETICS_GROUP_EQUIPMENT,    ImVec4(160, 100,   0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale
+    COSMETIC_OPTION("Equipment_SlingshotString",     "Slingshot String",     COSMETICS_GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Equipment_HammerHead",          "Hammer Head",          COSMETICS_GROUP_EQUIPMENT,    ImVec4(155, 192, 201, 255), false, true, false),
+    COSMETIC_OPTION("Equipment_HammerHandle",        "Hammer Handle",        COSMETICS_GROUP_EQUIPMENT,    ImVec4(110,  60,   0, 255), false, true, true),
+    // COSMETIC_OPTION("Equipment_HookshotChain",       "Hookshot Chain",       COSMETICS_GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement
+    // COSMETIC_OPTION("Equipment_HookshotTip",         "Hookshot Tip",         COSMETICS_GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement
+    COSMETIC_OPTION("HookshotReticle_Target",        "Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT,         ImVec4(  0, 255,   0, 255), false, false, false),
+    COSMETIC_OPTION("HookshotReticle_NonTarget",     "Non-Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT,     ImVec4(255,   0,   0, 255), false, false, false),
+    COSMETIC_OPTION("Equipment_BowTips",             "Bow Tips",             COSMETICS_GROUP_EQUIPMENT,    ImVec4(200,   0,   0, 255), false, true, true),
+    COSMETIC_OPTION("Equipment_BowString",           "Bow String",           COSMETICS_GROUP_EQUIPMENT,    ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Equipment_BowBody",             "Bow Body",             COSMETICS_GROUP_EQUIPMENT,    ImVec4(140,  90,  10, 255), false, true, false),
+    COSMETIC_OPTION("Equipment_BowHandle",           "Bow Handle",           COSMETICS_GROUP_EQUIPMENT,    ImVec4( 50, 150, 255, 255), false, true, true),
+    COSMETIC_OPTION("Equipment_ChuFace",             "Bombchu Face",         COSMETICS_GROUP_EQUIPMENT,    ImVec4(  0, 100, 150, 255), false, true, true),
+    COSMETIC_OPTION("Equipment_ChuBody",             "Bombchu Body",         COSMETICS_GROUP_EQUIPMENT,    ImVec4(180, 130,  50, 255), false, true, true), 
+    COSMETIC_OPTION("Equipment_BunnyHood",           "Bunny Hood",           COSMETICS_GROUP_EQUIPMENT,    ImVec4(255, 235,  109, 255), false, true, true), 
 
-    COSMETIC_OPTION("Consumable_Hearts",             "Hearts",               GROUP_CONSUMABLE,   ImVec4(255,  70,  50, 255), false, true, false),
-    COSMETIC_OPTION("Consumable_HeartBorder",        "Heart Border",         GROUP_CONSUMABLE,   ImVec4( 50,  40,  60, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_DDHearts",           "DD Hearts",            GROUP_CONSUMABLE,   ImVec4(200,   0,   0, 255), false, true, false),
-    COSMETIC_OPTION("Consumable_DDHeartBorder",      "DD Heart Border",      GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_Magic",              "Magic",                GROUP_CONSUMABLE,   ImVec4(  0, 200,   0, 255), false, true, false),
-    COSMETIC_OPTION("Consumable_MagicActive",        "Magic Active",         GROUP_CONSUMABLE,   ImVec4(250, 250,   0, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_MagicBorder",        "Magic Border",         GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, false, true),
-    COSMETIC_OPTION("Consumable_MagicBorderActive",  "Magic Border Active",  GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, false, true),
-    COSMETIC_OPTION("Consumable_GreenRupee",         "Green Rupee",          GROUP_CONSUMABLE,   ImVec4( 50, 255,  50, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_BlueRupee",          "Blue Rupee",           GROUP_CONSUMABLE,   ImVec4( 50,  50, 255, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_RedRupee",           "Red Rupee",            GROUP_CONSUMABLE,   ImVec4(255,  50,  50, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_PurpleRupee",        "Purple Rupee",         GROUP_CONSUMABLE,   ImVec4(150,  50, 255, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_GoldRupee",          "Gold Rupee",           GROUP_CONSUMABLE,   ImVec4(255, 190,  55, 255), false, true, true),
-    COSMETIC_OPTION("Consumable_SilverRupee",        "Silver Rupee",         GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_Hearts",             "Hearts",               COSMETICS_GROUP_CONSUMABLE,   ImVec4(255,  70,  50, 255), false, true, false),
+    COSMETIC_OPTION("Consumable_HeartBorder",        "Heart Border",         COSMETICS_GROUP_CONSUMABLE,   ImVec4( 50,  40,  60, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_DDHearts",           "DD Hearts",            COSMETICS_GROUP_CONSUMABLE,   ImVec4(200,   0,   0, 255), false, true, false),
+    COSMETIC_OPTION("Consumable_DDHeartBorder",      "DD Heart Border",      COSMETICS_GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_Magic",              "Magic",                COSMETICS_GROUP_CONSUMABLE,   ImVec4(  0, 200,   0, 255), false, true, false),
+    COSMETIC_OPTION("Consumable_MagicActive",        "Magic Active",         COSMETICS_GROUP_CONSUMABLE,   ImVec4(250, 250,   0, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_MagicBorder",        "Magic Border",         COSMETICS_GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, false, true),
+    COSMETIC_OPTION("Consumable_MagicBorderActive",  "Magic Border Active",  COSMETICS_GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, false, true),
+    COSMETIC_OPTION("Consumable_GreenRupee",         "Green Rupee",          COSMETICS_GROUP_CONSUMABLE,   ImVec4( 50, 255,  50, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_BlueRupee",          "Blue Rupee",           COSMETICS_GROUP_CONSUMABLE,   ImVec4( 50,  50, 255, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_RedRupee",           "Red Rupee",            COSMETICS_GROUP_CONSUMABLE,   ImVec4(255,  50,  50, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_PurpleRupee",        "Purple Rupee",         COSMETICS_GROUP_CONSUMABLE,   ImVec4(150,  50, 255, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_GoldRupee",          "Gold Rupee",           COSMETICS_GROUP_CONSUMABLE,   ImVec4(255, 190,  55, 255), false, true, true),
+    COSMETIC_OPTION("Consumable_SilverRupee",        "Silver Rupee",         COSMETICS_GROUP_CONSUMABLE,   ImVec4(255, 255, 255, 255), false, true, true),
 
-    COSMETIC_OPTION("Hud_AButton",                   "A Button",             GROUP_HUD,          ImVec4( 90,  90, 255, 255), false, true, false),
-    COSMETIC_OPTION("Hud_BButton",                   "B Button",             GROUP_HUD,          ImVec4(  0, 150,   0, 255), false, true, false),
-    COSMETIC_OPTION("Hud_CButtons",                  "C Buttons",            GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, false),
-    COSMETIC_OPTION("Hud_CUpButton",                 "C Up Button",          GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_CDownButton",               "C Down Button",        GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_CLeftButton",               "C Left Button",        GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_CRightButton",              "C Right Button",       GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_StartButton",               "Start Button",         GROUP_HUD,          ImVec4(200,   0,   0, 255), false, true, false),
-    COSMETIC_OPTION("Hud_Dpad",                      "Dpad",                 GROUP_HUD,          ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Hud_KeyCount",                  "Key Count",            GROUP_HUD,          ImVec4(200, 230, 255, 255), false, true, true),
-    COSMETIC_OPTION("Hud_StoneOfAgony",              "Stone of Agony",       GROUP_HUD,          ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Hud_Minimap",                   "Minimap",              GROUP_HUD,          ImVec4(  0, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Hud_MinimapPosition",           "Minimap Position",     GROUP_HUD,          ImVec4(200, 255,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_MinimapEntrance",           "Minimap Entrance",     GROUP_HUD,          ImVec4(200,   0,   0, 255), false, true, true),
-    COSMETIC_OPTION("Hud_EnemyHealthBar",            "Enemy Health Bar",     GROUP_HUD,          ImVec4(255,   0,   0, 255), true, true, false),
-    COSMETIC_OPTION("Hud_EnemyHealthBorder",         "Enemy Health Border",  GROUP_HUD,          ImVec4(255, 255, 255, 255), true, false, true),
-    COSMETIC_OPTION("Hud_NameTagActorText",          "Nametag Text",         GROUP_HUD,          ImVec4(255, 255, 255, 255), true, true, false),
-    COSMETIC_OPTION("Hud_NameTagActorBackground",    "Nametag Background",   GROUP_HUD,          ImVec4(0,     0,   0,  80), true, false, true),
+    COSMETIC_OPTION("Hud_AButton",                   "A Button",             COSMETICS_GROUP_HUD,          ImVec4( 90,  90, 255, 255), false, true, false),
+    COSMETIC_OPTION("Hud_BButton",                   "B Button",             COSMETICS_GROUP_HUD,          ImVec4(  0, 150,   0, 255), false, true, false),
+    COSMETIC_OPTION("Hud_CButtons",                  "C Buttons",            COSMETICS_GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, false),
+    COSMETIC_OPTION("Hud_CUpButton",                 "C Up Button",          COSMETICS_GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_CDownButton",               "C Down Button",        COSMETICS_GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_CLeftButton",               "C Left Button",        COSMETICS_GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_CRightButton",              "C Right Button",       COSMETICS_GROUP_HUD,          ImVec4(255, 160,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_StartButton",               "Start Button",         COSMETICS_GROUP_HUD,          ImVec4(200,   0,   0, 255), false, true, false),
+    COSMETIC_OPTION("Hud_Dpad",                      "Dpad",                 COSMETICS_GROUP_HUD,          ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Hud_KeyCount",                  "Key Count",            COSMETICS_GROUP_HUD,          ImVec4(200, 230, 255, 255), false, true, true),
+    COSMETIC_OPTION("Hud_StoneOfAgony",              "Stone of Agony",       COSMETICS_GROUP_HUD,          ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Hud_Minimap",                   "Minimap",              COSMETICS_GROUP_HUD,          ImVec4(  0, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Hud_MinimapPosition",           "Minimap Position",     COSMETICS_GROUP_HUD,          ImVec4(200, 255,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_MinimapEntrance",           "Minimap Entrance",     COSMETICS_GROUP_HUD,          ImVec4(200,   0,   0, 255), false, true, true),
+    COSMETIC_OPTION("Hud_EnemyHealthBar",            "Enemy Health Bar",     COSMETICS_GROUP_HUD,          ImVec4(255,   0,   0, 255), true, true, false),
+    COSMETIC_OPTION("Hud_EnemyHealthBorder",         "Enemy Health Border",  COSMETICS_GROUP_HUD,          ImVec4(255, 255, 255, 255), true, false, true),
+    COSMETIC_OPTION("Hud_NameTagActorText",          "Nametag Text",         COSMETICS_GROUP_HUD,          ImVec4(255, 255, 255, 255), true, true, false),
+    COSMETIC_OPTION("Hud_NameTagActorBackground",    "Nametag Background",   COSMETICS_GROUP_HUD,          ImVec4(0,     0,   0,  80), true, false, true),
 
-    COSMETIC_OPTION("Kal_ItemSelA",                  "Item Select Color",    GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, false),
-    COSMETIC_OPTION("Kal_ItemSelB",                  "Item Select Color B",  GROUP_KALEIDO,      ImVec4(70,  100, 130, 255), false, true, true),
-    COSMETIC_OPTION("Kal_ItemSelC",                  "Item Select Color C",  GROUP_KALEIDO,      ImVec4(70,  100, 130, 255), false, true, true),
-    COSMETIC_OPTION("Kal_ItemSelD",                  "Item Select Color D",  GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, true),
+    COSMETIC_OPTION("Kal_ItemSelA",                  "Item Select Color",    COSMETICS_GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, false),
+    COSMETIC_OPTION("Kal_ItemSelB",                  "Item Select Color B",  COSMETICS_GROUP_KALEIDO,      ImVec4(70,  100, 130, 255), false, true, true),
+    COSMETIC_OPTION("Kal_ItemSelC",                  "Item Select Color C",  COSMETICS_GROUP_KALEIDO,      ImVec4(70,  100, 130, 255), false, true, true),
+    COSMETIC_OPTION("Kal_ItemSelD",                  "Item Select Color D",  COSMETICS_GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, true),
 
-    COSMETIC_OPTION("Kal_EquipSelA",                 "Equip Select Color",   GROUP_KALEIDO,      ImVec4(10,   50,  40, 255), false, true, false),
-    COSMETIC_OPTION("Kal_EquipSelB",                 "Equip Select Color B", GROUP_KALEIDO,      ImVec4(90,  100,  60, 255), false, true, true),
-    COSMETIC_OPTION("Kal_EquipSelC",                 "Equip Select Color C", GROUP_KALEIDO,      ImVec4(90,  100,  60, 255), false, true, true),
-    COSMETIC_OPTION("Kal_EquipSelD",                 "Equip Select Color D", GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, true),
+    COSMETIC_OPTION("Kal_EquipSelA",                 "Equip Select Color",   COSMETICS_GROUP_KALEIDO,      ImVec4(10,   50,  40, 255), false, true, false),
+    COSMETIC_OPTION("Kal_EquipSelB",                 "Equip Select Color B", COSMETICS_GROUP_KALEIDO,      ImVec4(90,  100,  60, 255), false, true, true),
+    COSMETIC_OPTION("Kal_EquipSelC",                 "Equip Select Color C", COSMETICS_GROUP_KALEIDO,      ImVec4(90,  100,  60, 255), false, true, true),
+    COSMETIC_OPTION("Kal_EquipSelD",                 "Equip Select Color D", COSMETICS_GROUP_KALEIDO,      ImVec4(10,   50,  80, 255), false, true, true),
 
-    COSMETIC_OPTION("Kal_MapSelDunA",                "Map Dungeon Color",    GROUP_KALEIDO,      ImVec4(80,   40,  30, 255), false, true, true),
-    COSMETIC_OPTION("Kal_MapSelDunB",                "Map Dungeon Color B",  GROUP_KALEIDO,      ImVec4(140,  60,  60, 255), false, true, true),
-    COSMETIC_OPTION("Kal_MapSelDunC",                "Map Dungeon Color C",  GROUP_KALEIDO,      ImVec4(140,  60,  60, 255), false, true, true),
-    COSMETIC_OPTION("Kal_MapSelDunD",                "Map Dungeon Color D",  GROUP_KALEIDO,      ImVec4(80,   40,  30, 255), false, true, true),
+    COSMETIC_OPTION("Kal_MapSelDunA",                "Map Dungeon Color",    COSMETICS_GROUP_KALEIDO,      ImVec4(80,   40,  30, 255), false, true, true),
+    COSMETIC_OPTION("Kal_MapSelDunB",                "Map Dungeon Color B",  COSMETICS_GROUP_KALEIDO,      ImVec4(140,  60,  60, 255), false, true, true),
+    COSMETIC_OPTION("Kal_MapSelDunC",                "Map Dungeon Color C",  COSMETICS_GROUP_KALEIDO,      ImVec4(140,  60,  60, 255), false, true, true),
+    COSMETIC_OPTION("Kal_MapSelDunD",                "Map Dungeon Color D",  COSMETICS_GROUP_KALEIDO,      ImVec4(80,   40,  30, 255), false, true, true),
 
-    COSMETIC_OPTION("Kal_QuestStatusA",              "Quest Status Color",   GROUP_KALEIDO,      ImVec4(80, 80, 50, 255),    false, true, false),
-    COSMETIC_OPTION("Kal_QuestStatusB",              "Quest Status Color B", GROUP_KALEIDO,      ImVec4(120, 120, 70, 255),  false, true, true),
-    COSMETIC_OPTION("Kal_QuestStatusC",              "Quest Status Color C", GROUP_KALEIDO,      ImVec4(120, 120, 70, 255),  false, true, true),
-    COSMETIC_OPTION("Kal_QuestStatusD",              "Quest Status Color D", GROUP_KALEIDO,      ImVec4(80, 80, 50, 255),    false, true, true),
+    COSMETIC_OPTION("Kal_QuestStatusA",              "Quest Status Color",   COSMETICS_GROUP_KALEIDO,      ImVec4(80, 80, 50, 255),    false, true, false),
+    COSMETIC_OPTION("Kal_QuestStatusB",              "Quest Status Color B", COSMETICS_GROUP_KALEIDO,      ImVec4(120, 120, 70, 255),  false, true, true),
+    COSMETIC_OPTION("Kal_QuestStatusC",              "Quest Status Color C", COSMETICS_GROUP_KALEIDO,      ImVec4(120, 120, 70, 255),  false, true, true),
+    COSMETIC_OPTION("Kal_QuestStatusD",              "Quest Status Color D", COSMETICS_GROUP_KALEIDO,      ImVec4(80, 80, 50, 255),    false, true, true),
 
-    COSMETIC_OPTION("Kal_MapSelectA",                "Map Color",            GROUP_KALEIDO,      ImVec4(80, 40, 30, 255),    false, true, false),
-    COSMETIC_OPTION("Kal_MapSelectB",                "Map Color B",          GROUP_KALEIDO,      ImVec4(140, 60, 60, 255),   false, true, true),
-    COSMETIC_OPTION("Kal_MapSelectC",                "Map Color C",          GROUP_KALEIDO,      ImVec4(140, 60, 60, 255),   false, true, true),
-    COSMETIC_OPTION("Kal_MapSelectD",                "Map Color D",          GROUP_KALEIDO,      ImVec4(80, 40, 30, 255),    false, true, true),
+    COSMETIC_OPTION("Kal_MapSelectA",                "Map Color",            COSMETICS_GROUP_KALEIDO,      ImVec4(80, 40, 30, 255),    false, true, false),
+    COSMETIC_OPTION("Kal_MapSelectB",                "Map Color B",          COSMETICS_GROUP_KALEIDO,      ImVec4(140, 60, 60, 255),   false, true, true),
+    COSMETIC_OPTION("Kal_MapSelectC",                "Map Color C",          COSMETICS_GROUP_KALEIDO,      ImVec4(140, 60, 60, 255),   false, true, true),
+    COSMETIC_OPTION("Kal_MapSelectD",                "Map Color D",          COSMETICS_GROUP_KALEIDO,      ImVec4(80, 40, 30, 255),    false, true, true),
 
-    COSMETIC_OPTION("Kal_SaveA",                     "Save Color",           GROUP_KALEIDO,      ImVec4(50, 50, 50, 255),    false, true, false),
-    COSMETIC_OPTION("Kal_SaveB",                     "Save Color B",         GROUP_KALEIDO,      ImVec4(110, 110, 110, 255), false, true, true),
-    COSMETIC_OPTION("Kal_SaveC",                     "Save Color C",         GROUP_KALEIDO,      ImVec4(110, 110, 110, 255), false, true, true),
-    COSMETIC_OPTION("Kal_SaveD",                     "Save Color D",         GROUP_KALEIDO,      ImVec4(50, 50, 50, 255),    false, true, true),
+    COSMETIC_OPTION("Kal_SaveA",                     "Save Color",           COSMETICS_GROUP_KALEIDO,      ImVec4(50, 50, 50, 255),    false, true, false),
+    COSMETIC_OPTION("Kal_SaveB",                     "Save Color B",         COSMETICS_GROUP_KALEIDO,      ImVec4(110, 110, 110, 255), false, true, true),
+    COSMETIC_OPTION("Kal_SaveC",                     "Save Color C",         COSMETICS_GROUP_KALEIDO,      ImVec4(110, 110, 110, 255), false, true, true),
+    COSMETIC_OPTION("Kal_SaveD",                     "Save Color D",         COSMETICS_GROUP_KALEIDO,      ImVec4(50, 50, 50, 255),    false, true, true),
 
-    COSMETIC_OPTION("Kal_NamePanel",                 "Name Panel",           GROUP_KALEIDO,      ImVec4(90,100,130,255),     true, true, false),
+    COSMETIC_OPTION("Kal_NamePanel",                 "Name Panel",           COSMETICS_GROUP_KALEIDO,      ImVec4(90,100,130,255),     true, true, false),
 
-    COSMETIC_OPTION("Title_FileChoose",              "File Choose",          GROUP_TITLE,        ImVec4(100, 150, 255, 255), false, true, false),
-    COSMETIC_OPTION("Title_NintendoLogo",            "Nintendo Logo",        GROUP_TITLE,        ImVec4(  0,   0, 255, 255), false, true, true),
-    COSMETIC_OPTION("Title_N64LogoRed",              "N64 Red",              GROUP_TITLE,        ImVec4(150,   0,   0, 255), false, true, true),
-    COSMETIC_OPTION("Title_N64LogoBlue",             "N64 Blue",             GROUP_TITLE,        ImVec4(  0,  50, 150, 255), false, true, true),
-    COSMETIC_OPTION("Title_N64LogoGreen",            "N64 Green",            GROUP_TITLE,        ImVec4( 50, 100,   0, 255), false, true, true),
-    COSMETIC_OPTION("Title_N64LogoYellow",           "N64 Yellow",           GROUP_TITLE,        ImVec4(200, 150,   0, 255), false, true, true),
-    // COSMETIC_OPTION("Title_FirePrimary",             "Title Fire Primary",   GROUP_TITLE,        ImVec4(255, 255, 170, 255), false, true, false), // Todo (Cosmetics): Kinda complicated
-    // COSMETIC_OPTION("Title_FireSecondary",           "Title Fire Secondary", GROUP_TITLE,        ImVec4(255, 100,   0, 255), false, true, true), // Todo (Cosmetics): Kinda complicated
+    COSMETIC_OPTION("Title_FileChoose",              "File Choose",          COSMETICS_GROUP_TITLE,        ImVec4(100, 150, 255, 255), false, true, false),
+    COSMETIC_OPTION("Title_NintendoLogo",            "Nintendo Logo",        COSMETICS_GROUP_TITLE,        ImVec4(  0,   0, 255, 255), false, true, true),
+    COSMETIC_OPTION("Title_N64LogoRed",              "N64 Red",              COSMETICS_GROUP_TITLE,        ImVec4(150,   0,   0, 255), false, true, true),
+    COSMETIC_OPTION("Title_N64LogoBlue",             "N64 Blue",             COSMETICS_GROUP_TITLE,        ImVec4(  0,  50, 150, 255), false, true, true),
+    COSMETIC_OPTION("Title_N64LogoGreen",            "N64 Green",            COSMETICS_GROUP_TITLE,        ImVec4( 50, 100,   0, 255), false, true, true),
+    COSMETIC_OPTION("Title_N64LogoYellow",           "N64 Yellow",           COSMETICS_GROUP_TITLE,        ImVec4(200, 150,   0, 255), false, true, true),
+    // COSMETIC_OPTION("Title_FirePrimary",             "Title Fire Primary",   COSMETICS_GROUP_TITLE,        ImVec4(255, 255, 170, 255), false, true, false), // Todo (Cosmetics): Kinda complicated
+    // COSMETIC_OPTION("Title_FireSecondary",           "Title Fire Secondary", COSMETICS_GROUP_TITLE,        ImVec4(255, 100,   0, 255), false, true, true), // Todo (Cosmetics): Kinda complicated
 
-    COSMETIC_OPTION("Arrows_NormalPrimary",          "Normal Primary",       GROUP_ARROWS,       ImVec4(  0, 150,   0,   0), false, true, false),
-    COSMETIC_OPTION("Arrows_NormalSecondary",        "Normal Secondary",     GROUP_ARROWS,       ImVec4(255, 255, 170, 255), false, true, true),
-    COSMETIC_OPTION("Arrows_FirePrimary",            "Fire Primary",         GROUP_ARROWS,       ImVec4(255, 200,   0,   0), false, true, false),
-    COSMETIC_OPTION("Arrows_FireSecondary",          "Fire Secondary",       GROUP_ARROWS,       ImVec4(255,   0,   0, 255), false, true, true),
-    COSMETIC_OPTION("Arrows_IcePrimary",             "Ice Primary",          GROUP_ARROWS,       ImVec4(  0,   0, 255, 255), false, true, false),
-    COSMETIC_OPTION("Arrows_IceSecondary",           "Ice Secondary",        GROUP_ARROWS,       ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Arrows_LightPrimary",           "Light Primary",        GROUP_ARROWS,       ImVec4(255, 255,   0, 255), false, true, false),
-    COSMETIC_OPTION("Arrows_LightSecondary",         "Light Secondary",      GROUP_ARROWS,       ImVec4(255, 255, 170,   0), false, true, true),
+    COSMETIC_OPTION("Arrows_NormalPrimary",          "Normal Primary",       COSMETICS_GROUP_ARROWS,       ImVec4(  0, 150,   0,   0), false, true, false),
+    COSMETIC_OPTION("Arrows_NormalSecondary",        "Normal Secondary",     COSMETICS_GROUP_ARROWS,       ImVec4(255, 255, 170, 255), false, true, true),
+    COSMETIC_OPTION("Arrows_FirePrimary",            "Fire Primary",         COSMETICS_GROUP_ARROWS,       ImVec4(255, 200,   0,   0), false, true, false),
+    COSMETIC_OPTION("Arrows_FireSecondary",          "Fire Secondary",       COSMETICS_GROUP_ARROWS,       ImVec4(255,   0,   0, 255), false, true, true),
+    COSMETIC_OPTION("Arrows_IcePrimary",             "Ice Primary",          COSMETICS_GROUP_ARROWS,       ImVec4(  0,   0, 255, 255), false, true, false),
+    COSMETIC_OPTION("Arrows_IceSecondary",           "Ice Secondary",        COSMETICS_GROUP_ARROWS,       ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Arrows_LightPrimary",           "Light Primary",        COSMETICS_GROUP_ARROWS,       ImVec4(255, 255,   0, 255), false, true, false),
+    COSMETIC_OPTION("Arrows_LightSecondary",         "Light Secondary",      COSMETICS_GROUP_ARROWS,       ImVec4(255, 255, 170,   0), false, true, true),
 
-    // COSMETIC_OPTION("Magic_DinsPrimary",             "Din's Primary",        GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gDF_Col
-    // COSMETIC_OPTION("Magic_DinsSecondary",           "Din's Secondary",      GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gDF_Env
-    // COSMETIC_OPTION("Magic_FaroresPrimary",          "Farore's Primary",     GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement
-    // COSMETIC_OPTION("Magic_FaroresSecondary",        "Farore's Secondary",   GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement
-    // COSMETIC_OPTION("Magic_NayrusPrimary",           "Nayru's Primary",      GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gNL_Diamond_Col / gNL_Orb_Col
-    // COSMETIC_OPTION("Magic_NayrusSecondary",         "Nayru's Secondary",    GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gNL_Diamond_Env / gNL_Orb_Env
+    // COSMETIC_OPTION("Magic_DinsPrimary",             "Din's Primary",        COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gDF_Col
+    // COSMETIC_OPTION("Magic_DinsSecondary",           "Din's Secondary",      COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gDF_Env
+    // COSMETIC_OPTION("Magic_FaroresPrimary",          "Farore's Primary",     COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement
+    // COSMETIC_OPTION("Magic_FaroresSecondary",        "Farore's Secondary",   COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement
+    // COSMETIC_OPTION("Magic_NayrusPrimary",           "Nayru's Primary",      COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gNL_Diamond_Col / gNL_Orb_Col
+    // COSMETIC_OPTION("Magic_NayrusSecondary",         "Nayru's Secondary",    COSMETICS_GROUP_MAGIC,        ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gNL_Diamond_Env / gNL_Orb_Env
 
-    COSMETIC_OPTION("SpinAttack_Level1Primary",      "Level 1 Primary",      GROUP_SPIN_ATTACK,  ImVec4(170, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("SpinAttack_Level1Secondary",    "Level 1 Secondary",    GROUP_SPIN_ATTACK,  ImVec4(  0, 100, 255, 255), false, true, false),
-    COSMETIC_OPTION("SpinAttack_Level2Primary",      "Level 2 Primary",      GROUP_SPIN_ATTACK,  ImVec4(255, 255, 170, 255), false, true, true),
-    COSMETIC_OPTION("SpinAttack_Level2Secondary",    "Level 2 Secondary",    GROUP_SPIN_ATTACK,  ImVec4(255, 100,   0, 255), false, true, false),
+    COSMETIC_OPTION("SpinAttack_Level1Primary",      "Level 1 Primary",      COSMETICS_GROUP_SPIN_ATTACK,  ImVec4(170, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("SpinAttack_Level1Secondary",    "Level 1 Secondary",    COSMETICS_GROUP_SPIN_ATTACK,  ImVec4(  0, 100, 255, 255), false, true, false),
+    COSMETIC_OPTION("SpinAttack_Level2Primary",      "Level 2 Primary",      COSMETICS_GROUP_SPIN_ATTACK,  ImVec4(255, 255, 170, 255), false, true, true),
+    COSMETIC_OPTION("SpinAttack_Level2Secondary",    "Level 2 Secondary",    COSMETICS_GROUP_SPIN_ATTACK,  ImVec4(255, 100,   0, 255), false, true, false),
 
-    COSMETIC_OPTION("Trails_Bombchu",                "Bombchu",              GROUP_TRAILS,       ImVec4(250,   0,   0, 255), false, true, true),
-    COSMETIC_OPTION("Trails_Boomerang",              "Boomerang",            GROUP_TRAILS,       ImVec4(255, 255, 100, 255), false, true, true),
-    COSMETIC_OPTION("Trails_KokiriSword",            "Kokiri Sword",         GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Trails_MasterSword",            "Master Sword",         GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Trails_BiggoronSword",          "Biggoron Sword",       GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Trails_Stick",                  "Stick",                GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("Trails_Hammer",                 "Hammer",               GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Trails_Bombchu",                "Bombchu",              COSMETICS_GROUP_TRAILS,       ImVec4(250,   0,   0, 255), false, true, true),
+    COSMETIC_OPTION("Trails_Boomerang",              "Boomerang",            COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 100, 255), false, true, true),
+    COSMETIC_OPTION("Trails_KokiriSword",            "Kokiri Sword",         COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Trails_MasterSword",            "Master Sword",         COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Trails_BiggoronSword",          "Biggoron Sword",       COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Trails_Stick",                  "Stick",                COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("Trails_Hammer",                 "Hammer",               COSMETICS_GROUP_TRAILS,       ImVec4(255, 255, 255, 255), false, true, true),
 
-    COSMETIC_OPTION("World_BlockOfTime",             "Block of Time",        GROUP_WORLD,        ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("World_Moon",                    "Moon",                 GROUP_WORLD,        ImVec4(240, 255, 180, 255), false, true, true),
-    COSMETIC_OPTION("World_GossipStone",             "Gossip Stone",         GROUP_WORLD,        ImVec4(200, 200, 200, 255), false, true, true),
-    COSMETIC_OPTION("World_RedIce",                  "Red Ice",              GROUP_WORLD,        ImVec4(255,   0,   0, 255), false, true, false),
+    COSMETIC_OPTION("World_BlockOfTime",             "Block of Time",        COSMETICS_GROUP_WORLD,        ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("World_Moon",                    "Moon",                 COSMETICS_GROUP_WORLD,        ImVec4(240, 255, 180, 255), false, true, true),
+    COSMETIC_OPTION("World_GossipStone",             "Gossip Stone",         COSMETICS_GROUP_WORLD,        ImVec4(200, 200, 200, 255), false, true, true),
+    COSMETIC_OPTION("World_RedIce",                  "Red Ice",              COSMETICS_GROUP_WORLD,        ImVec4(255,   0,   0, 255), false, true, false),
 
-    COSMETIC_OPTION("Navi_IdlePrimary",              "Idle Primary",         GROUP_NAVI,         ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Navi_IdleSecondary",            "Idle Secondary",       GROUP_NAVI,         ImVec4(  0,   0, 255,   0), false, true, true),
-    COSMETIC_OPTION("Navi_NPCPrimary",               "NPC Primary",          GROUP_NAVI,         ImVec4(150, 150, 255, 255), false, true, false),
-    COSMETIC_OPTION("Navi_NPCSecondary",             "NPC Secondary",        GROUP_NAVI,         ImVec4(150, 150, 255,   0), false, true, true),
-    COSMETIC_OPTION("Navi_EnemyPrimary",             "Enemy Primary",        GROUP_NAVI,         ImVec4(255, 255,   0, 255), false, true, false),
-    COSMETIC_OPTION("Navi_EnemySecondary",           "Enemy Secondary",      GROUP_NAVI,         ImVec4(200, 155,   0,   0), false, true, true),
-    COSMETIC_OPTION("Navi_PropsPrimary",             "Props Primary",        GROUP_NAVI,         ImVec4(  0, 255,   0, 255), false, true, false),
-    COSMETIC_OPTION("Navi_PropsSecondary",           "Props Secondary",      GROUP_NAVI,         ImVec4(  0, 255,   0,   0), false, true, true),
+    COSMETIC_OPTION("Navi_IdlePrimary",              "Idle Primary",         COSMETICS_GROUP_NAVI,         ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Navi_IdleSecondary",            "Idle Secondary",       COSMETICS_GROUP_NAVI,         ImVec4(  0,   0, 255,   0), false, true, true),
+    COSMETIC_OPTION("Navi_NPCPrimary",               "NPC Primary",          COSMETICS_GROUP_NAVI,         ImVec4(150, 150, 255, 255), false, true, false),
+    COSMETIC_OPTION("Navi_NPCSecondary",             "NPC Secondary",        COSMETICS_GROUP_NAVI,         ImVec4(150, 150, 255,   0), false, true, true),
+    COSMETIC_OPTION("Navi_EnemyPrimary",             "Enemy Primary",        COSMETICS_GROUP_NAVI,         ImVec4(255, 255,   0, 255), false, true, false),
+    COSMETIC_OPTION("Navi_EnemySecondary",           "Enemy Secondary",      COSMETICS_GROUP_NAVI,         ImVec4(200, 155,   0,   0), false, true, true),
+    COSMETIC_OPTION("Navi_PropsPrimary",             "Props Primary",        COSMETICS_GROUP_NAVI,         ImVec4(  0, 255,   0, 255), false, true, false),
+    COSMETIC_OPTION("Navi_PropsSecondary",           "Props Secondary",      COSMETICS_GROUP_NAVI,         ImVec4(  0, 255,   0,   0), false, true, true),
     
-    COSMETIC_OPTION("Ivan_IdlePrimary",              "Ivan Idle Primary",    GROUP_IVAN,         ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("Ivan_IdleSecondary",            "Ivan Idle Secondary",  GROUP_IVAN,         ImVec4(  0, 255,   0, 255), false, true, true),
+    COSMETIC_OPTION("Ivan_IdlePrimary",              "Ivan Idle Primary",    COSMETICS_GROUP_IVAN,         ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("Ivan_IdleSecondary",            "Ivan Idle Secondary",  COSMETICS_GROUP_IVAN,         ImVec4(  0, 255,   0, 255), false, true, true),
 
-    COSMETIC_OPTION("NPC_FireKeesePrimary",          "Fire Keese Primary",   GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("NPC_FireKeeseSecondary",        "Fire Keese Secondary", GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("NPC_IceKeesePrimary",           "Ice Keese Primary",    GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("NPC_IceKeeseSecondary",         "Ice Keese Secondary",  GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("NPC_FireKeesePrimary",          "Fire Keese Primary",   COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("NPC_FireKeeseSecondary",        "Fire Keese Secondary", COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("NPC_IceKeesePrimary",           "Ice Keese Primary",    COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("NPC_IceKeeseSecondary",         "Ice Keese Secondary",  COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
     // Todo (Cosmetics): Health fairy
-    COSMETIC_OPTION("NPC_Dog1",                      "Dog 1",                GROUP_NPC,          ImVec4(255, 255, 200, 255), false, true, true),
-    COSMETIC_OPTION("NPC_Dog2",                      "Dog 2",                GROUP_NPC,          ImVec4(150, 100,  50, 255), false, true, true),
-    COSMETIC_OPTION("NPC_GoldenSkulltula",           "Golden Skulltula",     GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
-    COSMETIC_OPTION("NPC_Kokiri",                    "Kokiri",               GROUP_NPC,          ImVec4(  0, 130,  70, 255), false, true, false),
-    COSMETIC_OPTION("NPC_Gerudo",                    "Gerudo",               GROUP_NPC,          ImVec4( 90,   0, 140, 255), false, true, false),
-    COSMETIC_OPTION("NPC_MetalTrap",                 "Metal Trap",           GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
-    COSMETIC_OPTION("NPC_IronKnuckles",              "Iron Knuckles",        GROUP_NPC,          ImVec4(245, 255, 205, 255), false, true, false),
+    COSMETIC_OPTION("NPC_Dog1",                      "Dog 1",                COSMETICS_GROUP_NPC,          ImVec4(255, 255, 200, 255), false, true, true),
+    COSMETIC_OPTION("NPC_Dog2",                      "Dog 2",                COSMETICS_GROUP_NPC,          ImVec4(150, 100,  50, 255), false, true, true),
+    COSMETIC_OPTION("NPC_GoldenSkulltula",           "Golden Skulltula",     COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, false),
+    COSMETIC_OPTION("NPC_Kokiri",                    "Kokiri",               COSMETICS_GROUP_NPC,          ImVec4(  0, 130,  70, 255), false, true, false),
+    COSMETIC_OPTION("NPC_Gerudo",                    "Gerudo",               COSMETICS_GROUP_NPC,          ImVec4( 90,   0, 140, 255), false, true, false),
+    COSMETIC_OPTION("NPC_MetalTrap",                 "Metal Trap",           COSMETICS_GROUP_NPC,          ImVec4(255, 255, 255, 255), false, true, true),
+    COSMETIC_OPTION("NPC_IronKnuckles",              "Iron Knuckles",        COSMETICS_GROUP_NPC,          ImVec4(245, 255, 205, 255), false, true, false),
 };
 
 static const char* MarginCvarList[] {
@@ -1778,19 +1756,19 @@ void CosmeticsEditorWindow::DrawElement() {
 
     if (ImGui::BeginTabBar("CosmeticsContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
         if (ImGui::BeginTabItem("Link & Items")) {
-            DrawCosmeticGroup(GROUP_LINK);
-            DrawCosmeticGroup(GROUP_GLOVES);
-            DrawCosmeticGroup(GROUP_MIRRORSHIELD);
-            DrawCosmeticGroup(GROUP_EQUIPMENT);
-            DrawCosmeticGroup(GROUP_SWORDS);
-            DrawCosmeticGroup(GROUP_CONSUMABLE);
+            DrawCosmeticGroup(COSMETICS_GROUP_LINK);
+            DrawCosmeticGroup(COSMETICS_GROUP_GLOVES);
+            DrawCosmeticGroup(COSMETICS_GROUP_MIRRORSHIELD);
+            DrawCosmeticGroup(COSMETICS_GROUP_EQUIPMENT);
+            DrawCosmeticGroup(COSMETICS_GROUP_SWORDS);
+            DrawCosmeticGroup(COSMETICS_GROUP_CONSUMABLE);
             ImGui::EndTabItem();
         }
         if (ImGui::BeginTabItem("Effects")) {
-            // DrawCosmeticGroup(GROUP_MAGIC); // Cosmetics TODO: Implement magic effect colors
-            DrawCosmeticGroup(GROUP_ARROWS);
-            DrawCosmeticGroup(GROUP_SPIN_ATTACK);
-            DrawCosmeticGroup(GROUP_TRAILS);
+            // DrawCosmeticGroup(COSMETICS_GROUP_MAGIC); // Cosmetics TODO: Implement magic effect colors
+            DrawCosmeticGroup(COSMETICS_GROUP_ARROWS);
+            DrawCosmeticGroup(COSMETICS_GROUP_SPIN_ATTACK);
+            DrawCosmeticGroup(COSMETICS_GROUP_TRAILS);
             if (UIWidgets::EnhancementSliderInt("Trails Duration: %d", "##Trails_Duration", "gCosmetics.Trails_Duration.Value", 2, 20, "", 4)) {
                 CVarSetInteger("gCosmetics.Trails_Duration.Changed", 1);
             }
@@ -1803,10 +1781,10 @@ void CosmeticsEditorWindow::DrawElement() {
             ImGui::EndTabItem();
         }
         if (ImGui::BeginTabItem("World & NPCs")) {
-            DrawCosmeticGroup(GROUP_WORLD);
-            DrawCosmeticGroup(GROUP_NAVI);
-            DrawCosmeticGroup(GROUP_IVAN);
-            DrawCosmeticGroup(GROUP_NPC);
+            DrawCosmeticGroup(COSMETICS_GROUP_WORLD);
+            DrawCosmeticGroup(COSMETICS_GROUP_NAVI);
+            DrawCosmeticGroup(COSMETICS_GROUP_IVAN);
+            DrawCosmeticGroup(COSMETICS_GROUP_NPC);
             ImGui::EndTabItem();
         }
         if (ImGui::BeginTabItem("Silly")) {
@@ -1814,8 +1792,8 @@ void CosmeticsEditorWindow::DrawElement() {
             ImGui::EndTabItem();
         }
         if (ImGui::BeginTabItem("HUD")) {
-            DrawCosmeticGroup(GROUP_HUD);
-            DrawCosmeticGroup(GROUP_TITLE);
+            DrawCosmeticGroup(COSMETICS_GROUP_HUD);
+            DrawCosmeticGroup(COSMETICS_GROUP_TITLE);
             ImGui::EndTabItem();
         }
 
@@ -1825,7 +1803,7 @@ void CosmeticsEditorWindow::DrawElement() {
         }
 
         if (ImGui::BeginTabItem("Pause Menu")) {
-            DrawCosmeticGroup(GROUP_KALEIDO);
+            DrawCosmeticGroup(COSMETICS_GROUP_KALEIDO);
             ImGui::EndTabItem();
         }
         ImGui::EndTabBar();
@@ -1885,6 +1863,19 @@ void CosmeticsEditor_RandomizeAll() {
     ApplyOrResetCustomGfxPatches();
 }
 
+void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) {
+    for (auto& [id, cosmeticOption] : cosmeticOptions) {
+        if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
+            (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) &&
+            cosmeticOption.group == group) {
+            RandomizeColor(cosmeticOption);
+        }
+    }
+
+    LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
+    ApplyOrResetCustomGfxPatches();
+}
+
 void CosmeticsEditor_ResetAll() {
     for (auto& [id, cosmeticOption] : cosmeticOptions) {
         if (!CVarGetInteger(cosmeticOption.lockedCvar, 0)) {
@@ -1895,3 +1886,14 @@ void CosmeticsEditor_ResetAll() {
     LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
     ApplyOrResetCustomGfxPatches();
 }
+
+void CosmeticsEditor_ResetGroup(CosmeticGroup group) {
+    for (auto& [id, cosmeticOption] : cosmeticOptions) {
+        if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && cosmeticOption.group == group) {
+            ResetColor(cosmeticOption);
+        }
+    }
+
+    LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
+    ApplyOrResetCustomGfxPatches();
+}
diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h
index b22a51ba7..9599a521f 100644
--- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h
+++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h
@@ -8,6 +8,29 @@
         ResourceMgr_UnpatchGfxByName(path, name); \
     }
 
+// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
+// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
+typedef enum {
+    COSMETICS_GROUP_LINK,
+    COSMETICS_GROUP_MIRRORSHIELD,
+    COSMETICS_GROUP_SWORDS,
+    COSMETICS_GROUP_GLOVES,
+    COSMETICS_GROUP_EQUIPMENT,
+    COSMETICS_GROUP_CONSUMABLE,
+    COSMETICS_GROUP_HUD,
+    COSMETICS_GROUP_KALEIDO,
+    COSMETICS_GROUP_TITLE,
+    COSMETICS_GROUP_NPC,
+    COSMETICS_GROUP_WORLD,
+    COSMETICS_GROUP_MAGIC,
+    COSMETICS_GROUP_ARROWS,
+    COSMETICS_GROUP_SPIN_ATTACK,
+    COSMETICS_GROUP_TRAILS,
+    COSMETICS_GROUP_NAVI,
+    COSMETICS_GROUP_IVAN,
+    COSMETICS_GROUP_MAX
+} CosmeticGroup;
+
 typedef struct {
     const std::string Name;
     const std::string ToolTip;
@@ -26,7 +49,9 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | Im
 void InitCosmeticsEditor();//Init the menu itself
 ImVec4 GetRandomValue(int MaximumPossible);
 void CosmeticsEditor_RandomizeAll();
+void CosmeticsEditor_RandomizeGroup(CosmeticGroup group);
 void CosmeticsEditor_ResetAll();
+void CosmeticsEditor_ResetGroup(CosmeticGroup group);
 void ApplyOrResetCustomGfxPatches(bool manualChange = true);
 
 class CosmeticsEditorWindow : public LUS::GuiWindow {
diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp
index 2c910a067..bbf72a6d3 100644
--- a/soh/soh/Enhancements/debugconsole.cpp
+++ b/soh/soh/Enhancements/debugconsole.cpp
@@ -1289,6 +1289,26 @@ static bool GenerateRandoHandler(std::shared_ptr<LUS::Console> Console, const st
     return 1;
 }
 
+static constexpr std::array<std::pair<const char*, CosmeticGroup>, COSMETICS_GROUP_MAX> cosmetic_groups = {{
+    {"link", COSMETICS_GROUP_LINK},
+    {"mirror_shield", COSMETICS_GROUP_MIRRORSHIELD},
+    {"swords", COSMETICS_GROUP_SWORDS},
+    {"gloves", COSMETICS_GROUP_GLOVES},
+    {"equipment", COSMETICS_GROUP_EQUIPMENT},
+    {"consumable", COSMETICS_GROUP_CONSUMABLE},
+    {"hud", COSMETICS_GROUP_HUD},
+    {"kaleido", COSMETICS_GROUP_KALEIDO},
+    {"title", COSMETICS_GROUP_TITLE},
+    {"npc", COSMETICS_GROUP_NPC},
+    {"world", COSMETICS_GROUP_WORLD},
+    {"magic", COSMETICS_GROUP_MAGIC},
+    {"arrows", COSMETICS_GROUP_ARROWS},
+    {"spin_attack", COSMETICS_GROUP_SPIN_ATTACK},
+    {"trials", COSMETICS_GROUP_TRAILS},
+    {"navi", COSMETICS_GROUP_NAVI},
+    {"ivan", COSMETICS_GROUP_IVAN},
+}};
+
 static bool CosmeticsHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
     if (args.size() < 2) {
         ERROR_MESSAGE("[SOH] Unexpected arguments passed");
@@ -1296,9 +1316,31 @@ static bool CosmeticsHandler(std::shared_ptr<LUS::Console> Console, const std::v
     }
 
     if (args[1].compare("reset") == 0) {
-        CosmeticsEditor_ResetAll();
+        if (args.size() == 2) {
+            CosmeticsEditor_ResetAll();
+        } else {
+            for (const auto& [key, value] : cosmetic_groups) {
+                if (args[2].compare(key) == 0) {
+                    CosmeticsEditor_ResetGroup(value);
+                    return 0;
+                }
+            }
+            ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
+            return 1;
+        }
     } else if (args[1].compare("randomize") == 0) {
-        CosmeticsEditor_RandomizeAll();
+        if (args.size() == 2) {
+            CosmeticsEditor_RandomizeAll();
+        } else {
+            for (const auto& [key, value] : cosmetic_groups) {
+                if (args[2].compare(key) == 0) {
+                    CosmeticsEditor_RandomizeGroup(value);
+                    return 0;
+                }
+            }
+            ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
+            return 1;
+        }
     } else {
         ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'");
         return 1;
@@ -1307,6 +1349,18 @@ static bool CosmeticsHandler(std::shared_ptr<LUS::Console> Console, const std::v
     return 0;
 }
 
+static std::map<std::string, SeqType> sfx_groups = {
+    {"bgm", SEQ_BGM_WORLD},
+    {"fanfares", SEQ_FANFARE},
+    {"events", SEQ_BGM_EVENT},
+    {"battle", SEQ_BGM_BATTLE},
+    {"ocarina", SEQ_OCARINA},
+    {"instruments", SEQ_INSTRUMENT},
+    {"sfx", SEQ_SFX},
+    {"voices", SEQ_VOICE},
+    {"custom", SEQ_BGM_CUSTOM},
+};
+
 static bool SfxHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
     if (args.size() < 2) {
         ERROR_MESSAGE("[SOH] Unexpected arguments passed");
@@ -1314,9 +1368,31 @@ static bool SfxHandler(std::shared_ptr<LUS::Console> Console, const std::vector<
     }
 
     if (args[1].compare("reset") == 0) {
-        AudioEditor_ResetAll();
+        if (args.size() == 2) {
+            AudioEditor_ResetAll();
+        } else {
+            for (const auto& [key, value] : sfx_groups) {
+                if (args[2].compare(key) == 0) {
+                    AudioEditor_ResetGroup(value);
+                    return 0;
+                }
+            }
+            ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
+            return 1;
+        }
     } else if (args[1].compare("randomize") == 0) {
-        AudioEditor_RandomizeAll();
+        if (args.size() == 2) {
+            AudioEditor_RandomizeAll();
+        } else {
+            for (const auto& [key, value] : sfx_groups) {
+                if (args[2].compare(key) == 0) {
+                    AudioEditor_RandomizeGroup(value);
+                    return 0;
+                }
+            }
+            ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
+            return 1;
+        }
     } else {
         ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'");
         return 1;
@@ -1506,10 +1582,12 @@ void DebugConsole_Init(void) {
 
     CMD_REGISTER("cosmetics", {CosmeticsHandler, "Change cosmetics.", {
             {"reset|randomize", LUS::ArgumentType::TEXT},
+            {"group name", LUS::ArgumentType::TEXT, true},
     }});
 
     CMD_REGISTER("sfx", {SfxHandler, "Change SFX.", {
             {"reset|randomize", LUS::ArgumentType::TEXT},
+            {"group_name", LUS::ArgumentType::TEXT, true},
     }});
 
     CVarSave();
diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp
index 9adbabadf..23aa82362 100644
--- a/soh/soh/SohMenuBar.cpp
+++ b/soh/soh/SohMenuBar.cpp
@@ -41,14 +41,6 @@ extern bool isBetaQuestEnabled;
 
 extern "C" PlayState* gPlayState;
 
-enum SeqPlayers {
-    /* 0 */ SEQ_BGM_MAIN,
-    /* 1 */ SEQ_FANFARE,
-    /* 2 */ SEQ_SFX,
-    /* 3 */ SEQ_BGM_SUB,
-    /* 4 */ SEQ_MAX
-};
-
 std::string GetWindowButtonText(const char* text, bool menuOpen) {
     char buttonText[100] = "";
     if (menuOpen) {
@@ -192,16 +184,16 @@ void DrawSettingsMenu() {
         if (ImGui::BeginMenu("Audio")) {
             UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %.1f %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true);
             if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %.1f %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
-                Audio_SetGameVolume(SEQ_BGM_MAIN, CVarGetFloat("gMainMusicVolume", 1.0f));
+                Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, CVarGetFloat("gMainMusicVolume", 1.0f));
             }
             if (UIWidgets::PaddedEnhancementSliderFloat("Sub Music Volume: %.1f %%", "##Sub_Music_Vol", "gSubMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
-                Audio_SetGameVolume(SEQ_BGM_SUB, CVarGetFloat("gSubMusicVolume", 1.0f));
+                Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, CVarGetFloat("gSubMusicVolume", 1.0f));
             }
             if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %.1f %%", "##Sound_Effect_Vol", "gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
-                Audio_SetGameVolume(SEQ_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
+                Audio_SetGameVolume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
             }
             if (UIWidgets::PaddedEnhancementSliderFloat("Fanfare Volume: %.1f %%", "##Fanfare_Vol", "gFanfareVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
-                Audio_SetGameVolume(SEQ_FANFARE, CVarGetFloat("gFanfareVolume", 1.0f));
+                Audio_SetGameVolume(SEQ_PLAYER_FANFARE, CVarGetFloat("gFanfareVolume", 1.0f));
             }
 
             static std::unordered_map<LUS::AudioBackend, const char*> audioBackendNames = {