From bda484557247a55eca8e3971b627771c3d0c2acd Mon Sep 17 00:00:00 2001 From: aMannus Date: Tue, 7 May 2024 16:10:55 +0200 Subject: [PATCH] [Enhancement] Always Win Doggy Race (#256) * Always Win Doggy Race Hookified * uint8_t -> bool * Trailing comma --------- Co-authored-by: Archez --- mm/2s2h/BenGui/BenMenuBar.cpp | 12 +++++++++++ mm/2s2h/Enhancements/Enhancements.cpp | 3 +++ mm/2s2h/Enhancements/Enhancements.h | 7 +++++++ .../GameInteractor/GameInteractor.h | 1 + .../Minigames/AlwaysWinDoggyRace.cpp | 20 +++++++++++++++++++ .../Minigames/AlwaysWinDoggyRace.h | 6 ++++++ .../actors/ovl_En_Racedog/z_en_racedog.c | 7 ++++++- 7 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.cpp create mode 100644 mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.h diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp index a72780496..527bb85d5 100644 --- a/mm/2s2h/BenGui/BenMenuBar.cpp +++ b/mm/2s2h/BenGui/BenMenuBar.cpp @@ -39,6 +39,12 @@ static std::unordered_map windowBackendsMap = { Ship::WindowBackend::GX2, "GX2" } }; +static const std::unordered_map alwaysWinDoggyraceOptions = { + { ALWAYS_WIN_DOGGY_RACE_OFF, "Off" }, + { ALWAYS_WIN_DOGGY_RACE_MASKOFTRUTH, "When owning Mask of Truth" }, + { ALWAYS_WIN_DOGGY_RACE_ALWAYS, "Always" }, +}; + namespace BenGui { void DrawMenuBarIcon() { @@ -353,6 +359,12 @@ void DrawEnhancementsMenu() { ImGui::EndMenu(); } + if (UIWidgets::BeginMenu("Minigames")) { + UIWidgets::CVarCombobox("Always Win Doggy Race", "gEnhancements.Minigames.AlwaysWinDoggyRace", alwaysWinDoggyraceOptions); + + ImGui::EndMenu(); + } + if (UIWidgets::BeginMenu("Modes")) { if (UIWidgets::CVarCheckbox("Play As Kafei", "gModes.PlayAsKafei", { .tooltip = "Requires scene reload to take effect." diff --git a/mm/2s2h/Enhancements/Enhancements.cpp b/mm/2s2h/Enhancements/Enhancements.cpp index 1c0e04064..65bddb64b 100644 --- a/mm/2s2h/Enhancements/Enhancements.cpp +++ b/mm/2s2h/Enhancements/Enhancements.cpp @@ -13,6 +13,9 @@ void InitEnhancements() { RegisterFierceDeityAnywhere(); RegisterNoBlastMaskCooldown(); + // Minigames + RegisterAlwaysWinDoggyRace(); + // Restorations RegisterSideRoll(); diff --git a/mm/2s2h/Enhancements/Enhancements.h b/mm/2s2h/Enhancements/Enhancements.h index 499d7d21f..c6035601b 100644 --- a/mm/2s2h/Enhancements/Enhancements.h +++ b/mm/2s2h/Enhancements/Enhancements.h @@ -8,11 +8,18 @@ #include "Masks/FierceDeityAnywhere.h" #include "Masks/NoBlastMaskCooldown.h" #include "Masks/FastTransformation.h" +#include "Minigames/AlwaysWinDoggyRace.h" #include "Cutscenes/SkipEntranceCutscenes.h" #include "Cutscenes/HideTitleCards.h" #include "Restorations/SideRoll.h" #include "Graphics/PlayAsKafei.h" +enum AlwaysWinDoggyRaceOptions { + ALWAYS_WIN_DOGGY_RACE_OFF, + ALWAYS_WIN_DOGGY_RACE_MASKOFTRUTH, + ALWAYS_WIN_DOGGY_RACE_ALWAYS, +}; + #ifdef __cplusplus extern "C" { #endif diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h index 736b1e31d..07825a8d3 100644 --- a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h @@ -32,6 +32,7 @@ typedef enum { GI_VB_SHOW_TITLE_CARD, GI_VB_PLAY_ENTRANCE_CS, GI_VB_DISABLE_FD_MASK, + GI_VB_DOGGY_RACE_SET_MAX_SPEED, GI_VB_LOWER_RAZOR_SWORD_DURABILITY, GI_VB_SET_BLAST_MASK_COOLDOWN_TIMER, GI_VB_PATCH_SIDEROLL, diff --git a/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.cpp b/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.cpp new file mode 100644 index 000000000..b0e00122c --- /dev/null +++ b/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.cpp @@ -0,0 +1,20 @@ +#include +#include "Enhancements/GameInteractor/GameInteractor.h" +#include "Enhancements/Enhancements.h" + +extern "C" { + #include + extern SaveContext gSaveContext; + extern u8 gItemSlots[77]; +} + + +void RegisterAlwaysWinDoggyRace() { + REGISTER_VB_SHOULD(GI_VB_DOGGY_RACE_SET_MAX_SPEED, { + uint8_t selectedOption = CVarGetInteger("gEnhancements.Minigames.AlwaysWinDoggyRace", 0); + if (selectedOption == ALWAYS_WIN_DOGGY_RACE_ALWAYS || (selectedOption == ALWAYS_WIN_DOGGY_RACE_MASKOFTRUTH && + (INV_CONTENT(ITEM_MASK_TRUTH) == ITEM_MASK_TRUTH))) { + *should = true; + } + }); +} diff --git a/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.h b/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.h new file mode 100644 index 000000000..90318122d --- /dev/null +++ b/mm/2s2h/Enhancements/Minigames/AlwaysWinDoggyRace.h @@ -0,0 +1,6 @@ +#ifndef MINIGAMES_ALWAYS_WIN_DOGGY_RACE_H +#define MINIGAMES_ALWAYS_WIN_DOGGY_RACE_H + +void RegisterAlwaysWinDoggyRace(); + +#endif // MINIGAMES_ALWAYS_WIN_DOGGY_RACE_H diff --git a/mm/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c b/mm/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c index 24c8d3b79..d49470f13 100644 --- a/mm/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c +++ b/mm/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c @@ -12,6 +12,8 @@ #include "overlays/actors/ovl_En_Aob_01/z_en_aob_01.h" #include "overlays/actors/ovl_En_Dg/z_en_dg.h" +#include "Enhancements/GameInteractor/GameInteractor.h" + #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnRacedog*)thisx) @@ -514,7 +516,10 @@ void EnRacedog_UpdateSpeed(EnRacedog* this) { // The dog that the player has selected has a slightly higher max speed than the other dogs. if (this->index == this->selectedDogIndex) { - if (this->actor.speed > 7.5f) { + + // Cap the speed of the dog, or always max it out with the 'Always Win Doggy Race' enhancement. + bool vanillaCondition = this->actor.speed > 7.5f; + if (GameInteractor_Should(GI_VB_DOGGY_RACE_SET_MAX_SPEED, vanillaCondition, NULL)) { this->actor.speed = 7.5f; } } else {