diff options
| -rw-r--r-- | soh/soh/Enhancements/Minigames/IngoRaceOnce.cpp | 20 | ||||
| -rw-r--r-- | soh/soh/Enhancements/enhancementTypes.h | 6 | ||||
| -rw-r--r-- | soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h | 8 | ||||
| -rw-r--r-- | soh/soh/SohGui/SohMenuEnhancements.cpp | 14 | ||||
| -rw-r--r-- | soh/src/overlays/actors/ovl_En_In/z_en_in.c | 5 |
5 files changed, 48 insertions, 5 deletions
diff --git a/soh/soh/Enhancements/Minigames/IngoRaceOnce.cpp b/soh/soh/Enhancements/Minigames/IngoRaceOnce.cpp index 8f1ed554f..8ba9b9044 100644 --- a/soh/soh/Enhancements/Minigames/IngoRaceOnce.cpp +++ b/soh/soh/Enhancements/Minigames/IngoRaceOnce.cpp @@ -1,15 +1,31 @@ +#include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" extern "C" { #include "functions.h" +extern SaveContext gSaveContext; +extern PlayState* gPlayState; } #define CVAR_INGO_RACE_ONCE_NAME CVAR_ENHANCEMENT("IngoRaceOnce") -#define CVAR_INGO_RACE_ONCE_VALUE CVarGetInteger(CVAR_INGO_RACE_ONCE_NAME, 0) +#define CVAR_INGO_RACE_ONCE_VALUE CVarGetInteger(CVAR_INGO_RACE_ONCE_NAME, INGO_RACE_TWICE) static void RegisterIngoRaceOnce() { - COND_VB_SHOULD(VB_LINK_WIN_EPONA, CVAR_INGO_RACE_ONCE_NAME, { *should = true; }); + COND_VB_SHOULD(VB_RACE_INGO, CVAR_INGO_RACE_ONCE_VALUE == INGO_RACE_NONE, { + s32 entranceIndex = va_arg(args, s32); + if (entranceIndex == 2 && (gSaveContext.eventInf[0] & 0x10) == 0) { + gPlayState->nextEntranceIndex = ENTR_LON_LON_RANCH_7; + gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0xF) | 0x8006; + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gSaveContext.timerState = TIMER_STATE_OFF; + Environment_ForcePlaySequence(NA_BGM_INGO); + *should = false; + } + }) + + COND_VB_SHOULD(VB_LINK_WIN_EPONA, CVAR_INGO_RACE_ONCE_VALUE != INGO_RACE_TWICE, { *should = true; }); } static RegisterShipInitFunc initFunc(RegisterIngoRaceOnce, { CVAR_INGO_RACE_ONCE_NAME }); diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index 7b4b79a6f..7311a00ab 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -119,6 +119,12 @@ typedef enum { } SleepingWaterfallType; typedef enum { + INGO_RACE_TWICE, + INGO_RACE_ONCE, + INGO_RACE_NONE, +} IngoRaceType; + +typedef enum { RANDOMIZE_OFF, RANDOMIZE_ON_NEW_SCENE, RANDOMIZE_ON_RANDO_GEN_ONLY, diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 58c60ba67..f81b47c91 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2282,6 +2282,14 @@ typedef enum { // true // ``` // #### `args` + // - `s32` (entrance index) + VB_RACE_INGO, + + // #### `result` + // ```c + // true + // ``` + // #### `args` // - `*EnRd` VB_REDEAD_GIBDO_FREEZE_LINK, diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index b9a134705..dccbb7237 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -55,6 +55,12 @@ static const std::map<int32_t, const char*> skipForcedDialogOptions = { { FORCED_DIALOG_SKIP_ALL, "All" }, }; +static const std::map<int32_t, const char*> ingoRaceOptions = { + { INGO_RACE_TWICE, "Twice" }, + { INGO_RACE_ONCE, "Once" }, + { INGO_RACE_NONE, "None" }, +}; + static const std::map<int32_t, const char*> timeTravelOptions = { { TIME_TRAVEL_DISABLED, "Disabled" }, { TIME_TRAVEL_OOT, "Ocarina of Time" }, @@ -1621,9 +1627,13 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip("Amy's block pushing puzzle instantly solved.")); AddWidget(path, "Ingo's Race", WIDGET_SEPARATOR_TEXT); - AddWidget(path, "Only Race Once", WIDGET_CVAR_CHECKBOX) + AddWidget(path, "Number of Races", WIDGET_CVAR_COMBOBOX) .CVar(CVAR_ENHANCEMENT("IngoRaceOnce")) - .Options(CheckboxOptions().Tooltip("Link only needs to race Ingo once to win Epona.")); + .Options(ComboboxOptions() + .ComboMap(ingoRaceOptions) + .DefaultIndex(INGO_RACE_TWICE) + .Tooltip("Number of races Link must win against Ingo to earn Epona. " + "Only works if Link is riding Epona, not the other rideable horse.")); path.column = SECTION_COLUMN_3; AddWidget(path, "Rupee Diving Game", WIDGET_SEPARATOR_TEXT); diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 7986b042c..aeee316cb 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -2,6 +2,7 @@ #include "overlays/actors/ovl_En_Horse/z_en_horse.h" #include "objects/object_in/object_in.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED) @@ -694,7 +695,9 @@ void func_80A7A568(EnIn* this, PlayState* play) { phi_a2 = 0; transitionType = TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST); } - func_80A79BAC(this, play, phi_a2, transitionType); + if (GameInteractor_Should(VB_RACE_INGO, true, phi_a2)) { + func_80A79BAC(this, play, phi_a2, transitionType); + } play->msgCtx.stateTimer = 0; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; |
