From a04ee354d4c786d9c6a568e8b6624997c55cbfea Mon Sep 17 00:00:00 2001 From: "Tina H. (sheepytina)" <99330992+sheepytina@users.noreply.github.com> Date: Tue, 31 Oct 2023 02:55:53 +1100 Subject: [PATCH] Add "Navi Targeting Colors" options to Controller LED Color (#3254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a (not yet functional) "Navi" option. * It works! * Slightly better name for this menu option. * Revert accidental commit of comments in z_en_elf.c * Renaming and tweaks. * Temporary fix(?) for compile error on non-Windows platforms. * … Just pretend this particular commit doesn't exist. :OHYEAH: * A more suitable fix. + Partial suggestions from review. In-progress implementation of Cosmetics Navi colours. * Convert relevant code to use Color_RGB8 sans alpha, matching the controller LED. Defaults are now labeled for clarity. * Revert back to Color_RGBA8. + Implement Cosmetics Navi colours. Add Color conversion functions. * Tidy comments. * Changed mind yet a third time. Uses Color_RGB8 sans alpha again. Uses CVarGetColor24 instead of CVarGetColor to drop alpha from cosmetics editor values, like how Tunic Colors does it. This of course does require me to go with the prior idea of storing the Navi colours without alpha channels. * Color type conversion functions removed as they're no longer needed. * Tidy up commented out code once more. * Fix a typo * Suggestion from code review. (Yeah nah you're totally right though.) * Correct indentation. * A minor goof in the comments was bothering me. --- soh/include/z64.h | 2 + .../controls/GameControlEditor.cpp | 5 +- soh/soh/OTRGlobals.cpp | 74 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/soh/include/z64.h b/soh/include/z64.h index 2172dcb74..23ffcfb17 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -2245,6 +2245,8 @@ typedef enum { LED_SOURCE_TUNIC_ORIGINAL, LED_SOURCE_TUNIC_COSMETICS, LED_SOURCE_HEALTH, + LED_SOURCE_NAVI_ORIGINAL, + LED_SOURCE_NAVI_COSMETICS, LED_SOURCE_CUSTOM } LEDColorSource; diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp index 3bd650637..935935c48 100644 --- a/soh/soh/Enhancements/controls/GameControlEditor.cpp +++ b/soh/soh/Enhancements/controls/GameControlEditor.cpp @@ -331,13 +331,14 @@ namespace GameControlEditor { void DrawLEDControlPanel(GameControlEditorWindow* window) { window->BeginGroupPanelPublic("LED Colors", ImGui::GetContentRegionAvail()); - static const char* ledSources[4] = { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors", "Custom" }; + static const char* ledSources[] = { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors", + "Original Navi Targeting Colors", "Cosmetics Navi Targeting Colors", "Custom" }; UIWidgets::PaddedText("Source"); UIWidgets::EnhancementCombobox("gLedColorSource", ledSources, LED_SOURCE_TUNIC_ORIGINAL); DrawHelpIcon("Health\n- Red when health critical (13-20% depending on max health)\n- Yellow when health < 40%. Green otherwise.\n\n" \ "Tunics: colors will mirror currently equipped tunic, whether original or the current values in Cosmetics Editor.\n\n" \ "Custom: single, solid color"); - if (CVarGetInteger("gLedColorSource", 1) == 3) { + if (CVarGetInteger("gLedColorSource", 1) == LED_SOURCE_CUSTOM) { UIWidgets::Spacer(3); auto port1Color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 }); ImVec4 colorVec = { port1Color.r / 255.0f, port1Color.g / 255.0f, port1Color.b / 255.0f, 1.0f }; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index eee6a622a..553caef7e 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -128,6 +128,34 @@ Color_RGB8 kokiriColor = { 0x1E, 0x69, 0x1B }; Color_RGB8 goronColor = { 0x64, 0x14, 0x00 }; Color_RGB8 zoraColor = { 0x00, 0xEC, 0x64 }; +// Same as NaviColor type from OoT src (z_actor.c), but modified to be sans alpha channel for Controller LED. +typedef struct { + Color_RGB8 inner; + Color_RGB8 outer; +} NaviColor_RGB8; + +static NaviColor_RGB8 defaultIdleColor = { { 255, 255, 255 }, { 0, 0, 255 } }; +static NaviColor_RGB8 defaultNPCColor = { { 150, 150, 255 }, { 150, 150, 255 } }; +static NaviColor_RGB8 defaultEnemyColor = { { 255, 255, 0 }, { 200, 155, 0 } }; +static NaviColor_RGB8 defaultPropsColor = { { 0, 255, 0 }, { 0, 255, 0 } }; + +// Labeled according to ActorCategory (included through ActorDB.h) +const NaviColor_RGB8 LEDColorDefaultNaviColorList[] = { + defaultPropsColor, // ACTORCAT_SWITCH Switch + defaultPropsColor, // ACTORCAT_BG Background (Prop type 1) + defaultIdleColor, // ACTORCAT_PLAYER Player + defaultPropsColor, // ACTORCAT_EXPLOSIVE Bomb + defaultNPCColor, // ACTORCAT_NPC NPC + defaultEnemyColor, // ACTORCAT_ENEMY Enemy + defaultPropsColor, // ACTORCAT_PROP Prop type 2 + defaultPropsColor, // ACTORCAT_ITEMACTION Item/Action + defaultPropsColor, // ACTORCAT_MISC Misc. + defaultEnemyColor, // ACTORCAT_BOSS Boss + defaultPropsColor, // ACTORCAT_DOOR Door + defaultPropsColor, // ACTORCAT_CHEST Chest + defaultPropsColor, // ACTORCAT_MAX +}; + // OTRTODO: A lot of these left in Japanese are used by the mempak manager. LUS does not currently support mempaks. Ignore unused ones. const char* constCameraStrings[] = { "INSUFFICIENT", @@ -1718,6 +1746,52 @@ Color_RGB8 GetColorForControllerLED() { break; } } + if (gPlayState && (source == LED_SOURCE_NAVI_ORIGINAL || source == LED_SOURCE_NAVI_COSMETICS)) { + Actor* arrowPointedActor = gPlayState->actorCtx.targetCtx.arrowPointedActor; + if (arrowPointedActor) { + ActorCategory category = (ActorCategory)arrowPointedActor->category; + switch (category) { + case ACTORCAT_PLAYER: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_IdlePrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_IdlePrimary.Value", defaultIdleColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + case ACTORCAT_NPC: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_NPCPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_NPCPrimary.Value", defaultNPCColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + case ACTORCAT_ENEMY: + case ACTORCAT_BOSS: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_EnemyPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_EnemyPrimary.Value", defaultEnemyColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + break; + default: + if (source == LED_SOURCE_NAVI_COSMETICS && + CVarGetInteger("gCosmetics.Navi_PropsPrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_PropsPrimary.Value", defaultPropsColor.inner); + break; + } + color = LEDColorDefaultNaviColorList[category].inner; + } + } else { // No target actor. + if (source == LED_SOURCE_NAVI_COSMETICS && CVarGetInteger("gCosmetics.Navi_IdlePrimary.Changed", 0)) { + color = CVarGetColor24("gCosmetics.Navi_IdlePrimary.Value", defaultIdleColor.inner); + } else { + color = LEDColorDefaultNaviColorList[ACTORCAT_PLAYER].inner; + } + } + } if (source == LED_SOURCE_CUSTOM) { color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 }); }