From af0ea33e086ded9063b5f43eca3408367928e56e Mon Sep 17 00:00:00 2001 From: Liam Scholte Date: Mon, 25 Nov 2024 20:25:59 -0800 Subject: [PATCH] [Enhancement] Adds options for when the deku palace guard search balls will appear (#866) * [Enhancement] Adds options for when the deku palace guard search balls will appear * Addresses review comments * Moves DekuGuardSearchBalls enhancement to difficulty options * Remove unused variadic argument --- mm/2s2h/BenGui/BenMenuBar.cpp | 14 ++++++++++++ mm/2s2h/BenGui/SearchableMenuItems.h | 18 ++++++++++++++- .../DekuGuardSearchBalls.cpp | 22 +++++++++++++++++++ .../DifficultyOptions/DifficultyOptions.h | 1 + mm/2s2h/Enhancements/Enhancements.cpp | 1 + mm/2s2h/Enhancements/Enhancements.h | 6 +++++ mm/2s2h/GameInteractor/GameInteractor.h | 1 + .../actors/ovl_En_Look_Nuts/z_en_look_nuts.c | 5 ++++- 8 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 mm/2s2h/Enhancements/DifficultyOptions/DekuGuardSearchBalls.cpp diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp index 06ea78d99c..84342d477a 100644 --- a/mm/2s2h/BenGui/BenMenuBar.cpp +++ b/mm/2s2h/BenGui/BenMenuBar.cpp @@ -68,6 +68,12 @@ static const std::unordered_map timeStopOptions = { { TIME_STOP_TEMPLES_DUNGEONS, "Temples + Mini Dungeons" }, }; +static const std::unordered_map dekuGuardSearchBallsOptions = { + { DEKU_GUARD_SEARCH_BALLS_NEVER, "Never" }, + { DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY, "Night Only" }, + { DEKU_GUARD_SEARCH_BALLS_ALWAYS, "Always" }, +}; + namespace BenGui { std::shared_ptr> availableWindowBackends; std::unordered_map availableWindowBackendsMap; @@ -789,6 +795,14 @@ void DrawEnhancementsMenu() { "swords. It may still steal other items." })) { RegisterDisableTakkuriSteal(); } + + UIWidgets::CVarCombobox( + "Deku Guard Search Balls", "gEnhancements.Cheats.DekuGuardSearchBalls", dekuGuardSearchBallsOptions, + { .tooltip = "Choose when to show the Deku Palace Guards' search balls\n" + "- Never: Never show the search balls. This matches Majora's Mask 3D behaviour\n" + "- Night Only: Only show the search balls at night. This matches original N64 behaviour.\n" + "- Always: Always show the search balls.", + .defaultIndex = DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY }); ImGui::EndMenu(); } diff --git a/mm/2s2h/BenGui/SearchableMenuItems.h b/mm/2s2h/BenGui/SearchableMenuItems.h index de72461f2a..59dffea4a2 100644 --- a/mm/2s2h/BenGui/SearchableMenuItems.h +++ b/mm/2s2h/BenGui/SearchableMenuItems.h @@ -426,6 +426,12 @@ static const std::unordered_map notificationPosition = { { 0, "Top Left" }, { 1, "Top Right" }, { 2, "Bottom Left" }, { 3, "Bottom Right" }, { 4, "Hidden" }, }; +static const std::unordered_map dekuGuardSearchBallsOptions = { + { DEKU_GUARD_SEARCH_BALLS_NEVER, "Never" }, + { DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY, "Night Only" }, + { DEKU_GUARD_SEARCH_BALLS_ALWAYS, "Always" }, +}; + void FreeLookPitchMinMax() { f32 maxY = CVarGetFloat("gEnhancements.Camera.FreeLook.MaxPitch", 72.0f); f32 minY = CVarGetFloat("gEnhancements.Camera.FreeLook.MinPitch", -49.0f); @@ -1404,6 +1410,7 @@ void AddEnhancements() { WIDGET_CVAR_CHECKBOX, {}, [](widgetInfo& info) { RegisterWoodfallMountainAppearance(); } } } } }); + enhancementsSidebar.push_back( { "Difficulty Options", 3, @@ -1412,7 +1419,16 @@ void AddEnhancements() { "Prevents the Takkuri from stealing key items like bottles and swords. It may still steal other items.", WIDGET_CVAR_CHECKBOX, {}, - [](widgetInfo& info) { RegisterDisableTakkuriSteal(); } } } } }); + [](widgetInfo& info) { RegisterDisableTakkuriSteal(); } }, + { "Deku Guard Search Balls", + "gEnhancements.Cheats.DekuGuardSearchBalls", + "Choose when to show the Deku Palace Guards' search balls\n" + "- Never: Never show the search balls. This matches Majora's Mask 3D behaviour\n" + "- Night Only: Only show the search balls at night. This matches original N64 behaviour.\n" + "- Always: Always show the search balls.", + WIDGET_CVAR_COMBOBOX, + { .defaultVariant = DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY, + .comboBoxOptions = dekuGuardSearchBallsOptions } } } } }); enhancementsSidebar.push_back({ "HUD Editor", 1, { // HUD Editor diff --git a/mm/2s2h/Enhancements/DifficultyOptions/DekuGuardSearchBalls.cpp b/mm/2s2h/Enhancements/DifficultyOptions/DekuGuardSearchBalls.cpp new file mode 100644 index 0000000000..20b34326dc --- /dev/null +++ b/mm/2s2h/Enhancements/DifficultyOptions/DekuGuardSearchBalls.cpp @@ -0,0 +1,22 @@ +#include +#include "2s2h/GameInteractor/GameInteractor.h" +#include "Enhancements/Enhancements.h" + +extern "C" { +#include "variables.h" +} + +void RegisterShowDekuGuardSearchBalls() { + REGISTER_VB_SHOULD(VB_DEKU_GUARD_SHOW_SEARCH_BALLS, { + uint8_t selectedOption = + CVarGetInteger("gEnhancements.Cheats.DekuGuardSearchBalls", DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY); + switch (selectedOption) { + case DEKU_GUARD_SEARCH_BALLS_NEVER: + *should = false; + break; + case DEKU_GUARD_SEARCH_BALLS_ALWAYS: + *should = true; + break; + } + }); +} diff --git a/mm/2s2h/Enhancements/DifficultyOptions/DifficultyOptions.h b/mm/2s2h/Enhancements/DifficultyOptions/DifficultyOptions.h index 5680ec0af9..8706cd177b 100644 --- a/mm/2s2h/Enhancements/DifficultyOptions/DifficultyOptions.h +++ b/mm/2s2h/Enhancements/DifficultyOptions/DifficultyOptions.h @@ -2,5 +2,6 @@ #define DIFFICULTY_OPTIONS_H void RegisterDisableTakkuriSteal(); +void RegisterShowDekuGuardSearchBalls(); #endif // DIFFICULTY_OPTIONS_H \ No newline at end of file diff --git a/mm/2s2h/Enhancements/Enhancements.cpp b/mm/2s2h/Enhancements/Enhancements.cpp index 52ce348eaf..653bcdc3b1 100644 --- a/mm/2s2h/Enhancements/Enhancements.cpp +++ b/mm/2s2h/Enhancements/Enhancements.cpp @@ -83,4 +83,5 @@ void InitEnhancements() { // Difficulty Options RegisterDisableTakkuriSteal(); + RegisterShowDekuGuardSearchBalls(); } diff --git a/mm/2s2h/Enhancements/Enhancements.h b/mm/2s2h/Enhancements/Enhancements.h index aaee6c43c7..a2064dfc06 100644 --- a/mm/2s2h/Enhancements/Enhancements.h +++ b/mm/2s2h/Enhancements/Enhancements.h @@ -42,6 +42,12 @@ enum CremiaRewardsOptions { CREMIA_REWARD_ALWAYS_RUPEE, }; +enum DekuGuardSearchBallsOptions { + DEKU_GUARD_SEARCH_BALLS_NIGHT_ONLY, + DEKU_GUARD_SEARCH_BALLS_NEVER, + DEKU_GUARD_SEARCH_BALLS_ALWAYS, +}; + #ifdef __cplusplus extern "C" { #endif diff --git a/mm/2s2h/GameInteractor/GameInteractor.h b/mm/2s2h/GameInteractor/GameInteractor.h index d097a625d9..6d53a76ce3 100644 --- a/mm/2s2h/GameInteractor/GameInteractor.h +++ b/mm/2s2h/GameInteractor/GameInteractor.h @@ -74,6 +74,7 @@ typedef enum { VB_TRANSFORM_THUNDER_MATRIX, VB_PLAY_HEART_CONTAINER_GET_FANFARE, VB_BE_HOOKSHOT_SURFACE, + VB_DEKU_GUARD_SHOW_SEARCH_BALLS, } GIVanillaBehavior; typedef enum { diff --git a/mm/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c b/mm/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c index 97103237c8..3d29166854 100644 --- a/mm/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c +++ b/mm/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c @@ -7,6 +7,8 @@ #include "z_en_look_nuts.h" #include "overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h" +#include "2s2h/GameInteractor/GameInteractor.h" + #define FLAGS (ACTOR_FLAG_80000000) #define THIS ((EnLookNuts*)thisx) @@ -354,9 +356,10 @@ void EnLookNuts_Update(Actor* thisx, PlayState* play) { if (!this->isPlayerDetected) { s16 effectFlags = SOLDERSRCHBALL_INVISIBLE; - if (gSaveContext.save.isNight) { + if (GameInteractor_Should(VB_DEKU_GUARD_SHOW_SEARCH_BALLS, gSaveContext.save.isNight)) { effectFlags = 0; } + if (Player_GetMask(play) != PLAYER_MASK_STONE) { EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->isPlayerDetected, effectFlags);