From c2e38f07483508f2460d6e66e919d96dee34d985 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 25 Jul 2024 19:47:38 +0200 Subject: [PATCH 01/48] Convert ocarina buttons & skip scarecrow song to VB --- .../game-interactor/GameInteractor.h | 7 +++ .../Enhancements/randomizer/hook_handlers.cpp | 49 +++++++++++++++++++ .../Enhancements/timesaver_hook_handlers.cpp | 6 +++ soh/src/code/code_800EC960.c | 11 +++-- soh/src/code/z_horse.c | 6 +-- .../actors/ovl_En_Kakasi2/z_en_kakasi2.c | 16 +----- .../ovl_kaleido_scope/z_kaleido_collect.c | 11 +++-- 7 files changed, 79 insertions(+), 27 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 2323e7222e2..ba927cfb0c9 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -242,6 +242,13 @@ typedef enum { ``` */ VB_DRAW_AMMO_COUNT, + VB_HAVE_OCARINA_NOTE_D4, + VB_HAVE_OCARINA_NOTE_D5, + VB_HAVE_OCARINA_NOTE_F4, + VB_HAVE_OCARINA_NOTE_B4, + VB_HAVE_OCARINA_NOTE_A4, + // Vanilla condition: false + VB_SKIP_SCARECROWS_SONG, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d5737d33da4..858022b857e 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1131,6 +1131,55 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case VB_HAVE_OCARINA_NOTE_D4: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A)) { + *should = false; + } + break; + } + case VB_HAVE_OCARINA_NOTE_D5: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP)) { + *should = false; + } + break; + } + case VB_HAVE_OCARINA_NOTE_F4: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN)) { + *should = false; + } + break; + } + case VB_HAVE_OCARINA_NOTE_B4: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT)) { + *should = false; + } + break; + } + case VB_HAVE_OCARINA_NOTE_A4: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT)) { + *should = false; + } + break; + } + case VB_SKIP_SCARECROWS_SONG: { + int ocarinaButtonCount = 0; + for (int i = VB_HAVE_OCARINA_NOTE_D4; i <= VB_HAVE_OCARINA_NOTE_A4; i++) { + if (GameInteractor_Should((GIVanillaBehavior)i, true, NULL)) { + ocarinaButtonCount++; + } + } + + if (ocarinaButtonCount < 2) { + *should = false; + break; + } + + if (gPlayState->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING && RAND_GET_OPTION(RSK_SKIP_SCARECROWS_SONG)) { + *should = true; + break; + } + break; + } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 81c7d772783..ead70bdec0c 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -636,6 +636,12 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case VB_SKIP_SCARECROWS_SONG: { + if (gPlayState->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING && CVarGetInteger(CVAR_ENHANCEMENT("InstantScarecrow"), 0) && gSaveContext.scarecrowSpawnSongSet) { + *should = true; + } + break; + } } } diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c index a1364b8a975..055c6360729 100644 --- a/soh/src/code/code_800EC960.c +++ b/soh/src/code/code_800EC960.c @@ -1,6 +1,7 @@ #include #include "global.h" #include "soh/Enhancements/audio/AudioEditor.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" // TODO: can these macros be shared between files? code_800F9280 seems to use // versions without any casts... @@ -1626,23 +1627,23 @@ void func_800ED458(s32 arg0) { } Audio_OcaUpdateBtnMap(customControls, dpad, rStick); - if (D_8016BA18 & sOcarinaD4BtnMap && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A))) { + if (D_8016BA18 & sOcarinaD4BtnMap && GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true, NULL)) { osSyncPrintf("Presss NA_KEY_D4 %08x\n", sOcarinaD4BtnMap); sCurOcarinaBtnVal = 2; sCurOcarinaBtnIdx = 0; - } else if (D_8016BA18 & sOcarinaF4BtnMap && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN))) { + } else if (D_8016BA18 & sOcarinaF4BtnMap && GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true, NULL)) { osSyncPrintf("Presss NA_KEY_F4 %08x\n", sOcarinaF4BtnMap); sCurOcarinaBtnVal = 5; sCurOcarinaBtnIdx = 1; - } else if (D_8016BA18 & sOcarinaA4BtnMap && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT))) { + } else if (D_8016BA18 & sOcarinaA4BtnMap && GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true, NULL)) { osSyncPrintf("Presss NA_KEY_A4 %08x\n", sOcarinaA4BtnMap); sCurOcarinaBtnVal = 9; sCurOcarinaBtnIdx = 2; - } else if (D_8016BA18 & sOcarinaB4BtnMap && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT))) { + } else if (D_8016BA18 & sOcarinaB4BtnMap && GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true, NULL)) { osSyncPrintf("Presss NA_KEY_B4 %08x\n", sOcarinaA4BtnMap); sCurOcarinaBtnVal = 0xB; sCurOcarinaBtnIdx = 3; - } else if (D_8016BA18 & sOcarinaD5BtnMap && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP))) { + } else if (D_8016BA18 & sOcarinaD5BtnMap && GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true, NULL)) { osSyncPrintf("Presss NA_KEY_D5 %08x\n", sOcarinaD5BtnMap); sCurOcarinaBtnVal = 0xE; sCurOcarinaBtnIdx = 4; diff --git a/soh/src/code/z_horse.c b/soh/src/code/z_horse.c index 48c76396ffe..1f242232eea 100644 --- a/soh/src/code/z_horse.c +++ b/soh/src/code/z_horse.c @@ -75,9 +75,9 @@ void func_8006D0EC(PlayState* play, Player* player) { } else if ((play->sceneNum == gSaveContext.horseData.scene) && (((Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) != 0) && (!IS_RANDO || (IS_RANDO && CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true, NULL) && + GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true, NULL) && + GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true, NULL) && (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE)))) || DREG(1) != 0)) { // "Set by existence of horse %d %d %d" osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene, Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED), diff --git a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c index c8bea148fa8..8b0bf8dea99 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c @@ -7,6 +7,7 @@ #include "z_en_kakasi2.h" #include "vt.h" #include "objects/object_ka/object_ka.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA | ACTOR_FLAG_NO_LOCKON) @@ -116,21 +117,8 @@ void func_80A90264(EnKakasi2* this, PlayState* play) { Player* player = GET_PLAYER(play); this->unk_194++; - - int ocarinaButtonCount = 0; - for (int i = RAND_INF_HAS_OCARINA_A; i <= RAND_INF_HAS_OCARINA_C_DOWN; i++) { - if (Flags_GetRandomizerInf(i)) { - ocarinaButtonCount++; - } - } - - bool hasTwoOcarinaButtons = !IS_RANDO || ocarinaButtonCount >= 2; - - bool skipScarecrow = hasTwoOcarinaButtons && play->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING && - ((CVarGetInteger(CVAR_ENHANCEMENT("InstantScarecrow"), 0) && gSaveContext.scarecrowSpawnSongSet) || - (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_SCARECROWS_SONG))); - if ((BREG(1) != 0) || skipScarecrow && (this->actor.xzDistToPlayer < this->maxSpawnDistance.x) && + if ((BREG(1) != 0) || GameInteractor_Should(VB_SKIP_SCARECROWS_SONG, false, NULL) && (this->actor.xzDistToPlayer < this->maxSpawnDistance.x) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < this->maxSpawnDistance.y)) { this->actor.draw = func_80A90948; Collider_InitCylinder(play, &this->collider); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c index c81a89c4e3b..b77130ca35a 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c @@ -2,6 +2,7 @@ #include "textures/parameter_static/parameter_static.h" #include "textures/icon_item_static/icon_item_static.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" extern const char* digitTextures[]; @@ -12,7 +13,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { aButtonColor = (Color_RGB8){ 80, 255, 150 }; } - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A)) { + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true, NULL)) { aButtonColor = (Color_RGB8){ 191, 191, 191 }; } @@ -24,7 +25,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); } - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP)) { + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true, NULL)) { cUpButtonColor = (Color_RGB8){ 191, 191, 191 }; } @@ -32,7 +33,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); } - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN)) { + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true, NULL)) { cDownButtonColor = (Color_RGB8){ 191, 191, 191 }; } @@ -40,7 +41,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); } - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT)) { + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true, NULL)) { cLeftButtonColor = (Color_RGB8){ 191, 191, 191 }; } @@ -48,7 +49,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); } - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT)) { + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true, NULL)) { cRightButtonColor = (Color_RGB8){ 191, 191, 191 }; } From 94d24b8acb3ded834b12fb9613765439a2c7631a Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 25 Jul 2024 21:26:43 +0200 Subject: [PATCH 02/48] Move most of boss rush & rupee/key counters to VB --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 59 ++++++++++++++++ soh/soh/Enhancements/boss-rush/BossRush.h | 1 + .../game-interactor/GameInteractor.h | 11 +++ soh/soh/Enhancements/mods.cpp | 3 +- .../Enhancements/randomizer/hook_handlers.cpp | 12 ++++ soh/soh/z_play_otr.cpp | 4 -- soh/src/code/z_parameter.c | 70 ++++++++----------- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 6 +- .../overlays/actors/ovl_Boss_Fd/z_boss_fd.c | 6 +- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 8 ++- .../actors/ovl_Boss_Goma/z_boss_goma.c | 6 +- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 12 +++- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 8 ++- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 6 +- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 8 ++- soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 5 -- soh/src/overlays/actors/ovl_En_Box/z_en_box.h | 5 ++ .../overlays/actors/ovl_En_Kusa/z_en_kusa.c | 5 -- .../actors/ovl_Obj_Tsubo/z_obj_tsubo.c | 5 -- 19 files changed, 162 insertions(+), 78 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 9dbbad52748..e62782bac23 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -8,6 +8,10 @@ #include #include +extern "C" { + #include "src/overlays/actors/ovl_En_Box/z_en_box.h" +} + typedef struct BossRushSetting { std::array name; std::vector> choices; @@ -487,3 +491,58 @@ void BossRush_SetEquipment(uint8_t linkAge) { gSaveContext.equips.cButtonSlots[button] = brCButtonSlots[button]; } } + +void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { + switch (id) { + case VB_SPAWN_HEART_CONTAINER: + case VB_RENDER_RUPEE_COUNTER: + *should = false; + break; + } +} + +void BossRush_OnActorInitHandler(void* actorRef) { + Actor* actor = static_cast(actorRef); + + // Remove chests in Boss Rush. Mainly for the chest in King Dodongo's boss room. + if (actor->id == ACTOR_EN_BOX) { + EnBox_SetupAction(actor, EnBox_Destroy); + return; + } + + // Remove bushes in Boss Rush. Used in Gohma's arena. + // Remove pots in Boss Rush. Used in Barinade's and Ganondorf's arenas. + if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO) { + Actor_Kill(actor); + return; + } +} + +void BossRush_OnSceneInitHandler(int16_t sceneNum) { + // Unpause the timer for Boss Rush when the scene loaded isn't the Chamber of Sages. + if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { + gSaveContext.isBossRushPaused = 0; + } +} + +void BossRush_RegisterHooks() { + static uint32_t onVanillaBehaviorHook = 0; + static uint32_t onSceneInitHook = 0; + static uint32_t onActorInitHook = 0; + + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); + GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + + onVanillaBehaviorHook = 0; + onSceneInitHook = 0; + onActorInitHook = 0; + + if (!IS_BOSS_RUSH) return; + + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnVanillaBehaviorHandler); + onSceneInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); + onActorInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); + }); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/boss-rush/BossRush.h b/soh/soh/Enhancements/boss-rush/BossRush.h index caa6ce86e5a..56337d40b92 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -15,6 +15,7 @@ void BossRush_HandleCompleteBoss(PlayState* play); const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language); const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language); uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex); +void BossRush_RegisterHooks(); #ifdef __cplusplus }; #endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index ba927cfb0c9..97601d540d1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -242,13 +242,24 @@ typedef enum { ``` */ VB_DRAW_AMMO_COUNT, + // Vanilla condition: true VB_HAVE_OCARINA_NOTE_D4, + // Vanilla condition: true VB_HAVE_OCARINA_NOTE_D5, + // Vanilla condition: true VB_HAVE_OCARINA_NOTE_F4, + // Vanilla condition: true VB_HAVE_OCARINA_NOTE_B4, + // Vanilla condition: true VB_HAVE_OCARINA_NOTE_A4, // Vanilla condition: false VB_SKIP_SCARECROWS_SONG, + // Vanilla condition: true + VB_RENDER_RUPEE_COUNTER, + // Vanilla condition: true + VB_RENDER_KEY_COUNTER, + // Vanilla condition: true + VB_SPAWN_HEART_CONTAINER, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 2571b7d963c..af21f540bb4 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -3,7 +3,7 @@ #include "game-interactor/GameInteractor.h" #include "tts/tts.h" #include "soh/OTRGlobals.h" -#include "soh/Enhancements/boss-rush/BossRushTypes.h" +#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Enhancements/randomizer/fishsanity.h" @@ -1773,6 +1773,7 @@ void RegisterSkeletonKey() { } void InitMods() { + BossRush_RegisterHooks(); RandomizerRegisterHooks(); TimeSaverRegisterHooks(); CheatsRegisterHooks(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 858022b857e..78cdd1a32dc 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1180,6 +1180,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case VB_RENDER_KEY_COUNTER: { + if (Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { + *should = false; + } + break; + } + case VB_RENDER_RUPEE_COUNTER: { + if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) || Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) { + *should = false; + } + break; + } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 237b48ef37b..47e4279b274 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -77,10 +77,6 @@ void OTRPlay_InitScene(PlayState* play, s32 spawn) { gSaveContext.worldMapArea = 0; OTRScene_ExecuteCommands(play, (SOH::Scene*)play->sceneSegment); Play_InitEnvironment(play, play->skyboxId); - // Unpause the timer for Boss Rush when the scene loaded isn't the Chamber of Sages. - if (IS_BOSS_RUSH && play->sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { - gSaveContext.isBossRushPaused = 0; - } /* auto data = static_cast(Ship::Context::GetInstance() ->GetResourceManager() ->ResourceLoad("object_link_child\\object_link_childVtx_01FE08") diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 0cfde00b73f..189d751e0e4 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -5372,8 +5372,7 @@ void Interface_Draw(PlayState* play) { if (fullUi) { s16 PosX_RC; s16 PosY_RC; - //when not having a wallet (or infinite money) in rando, don't calculate the ruppe icon - if (!IS_RANDO || (Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) && !Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY))) { + if (GameInteractor_Should(VB_RENDER_RUPEE_COUNTER, true, NULL)) { // Rupee Icon if (CVarGetInteger(CVAR_ENHANCEMENT("DynamicWalletIcon"), 0)) { switch (CUR_UPG_VALUE(UPG_WALLET)) { @@ -5444,14 +5443,10 @@ void Interface_Draw(PlayState* play) { PosX_RC = PosX_RC_ori; } gDPSetPrimColor(OVERLAY_DISP++, 0, 0, rColor.r, rColor.g, rColor.b, interfaceCtx->magicAlpha); - // Draw Rupee icon. Hide in Boss Rush. - if (!IS_BOSS_RUSH) { - OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, PosX_RC, PosY_RC, 16, 16, 1 << 10, 1 << 10); - } + OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, PosX_RC, PosY_RC, 16, 16, 1 << 10, 1 << 10); } - //when having the skeleton key in rando, don't render the small key counter - if (!Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { + if (GameInteractor_Should(VB_RENDER_KEY_COUNTER, true, NULL)) { switch (play->sceneNum) { case SCENE_FOREST_TEMPLE: case SCENE_FIRE_TEMPLE: @@ -5467,7 +5462,6 @@ void Interface_Draw(PlayState* play) { case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: case SCENE_TREASURE_BOX_SHOP: - if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) { s16 X_Margins_SKC; s16 Y_Margins_SKC; @@ -5533,49 +5527,47 @@ void Interface_Draw(PlayState* play) { } } - // Rupee Counter - gDPPipeSync(OVERLAY_DISP++); + if (GameInteractor_Should(VB_RENDER_RUPEE_COUNTER, true, NULL)) { + // Rupee Counter + gDPPipeSync(OVERLAY_DISP++); - if (gSaveContext.rupees == CUR_CAPACITY(UPG_WALLET)) { - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, interfaceCtx->magicAlpha); - } else if (gSaveContext.rupees != 0) { - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha); - } else { - gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 100, 100, interfaceCtx->magicAlpha); - } + if (gSaveContext.rupees == CUR_CAPACITY(UPG_WALLET)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, interfaceCtx->magicAlpha); + } else if (gSaveContext.rupees != 0) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 100, 100, interfaceCtx->magicAlpha); + } - gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, - PRIMITIVE, 0); + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, + PRIMITIVE, 0); - interfaceCtx->counterDigits[0] = interfaceCtx->counterDigits[1] = 0; - interfaceCtx->counterDigits[2] = gSaveContext.rupees; + interfaceCtx->counterDigits[0] = interfaceCtx->counterDigits[1] = 0; + interfaceCtx->counterDigits[2] = gSaveContext.rupees; - if ((interfaceCtx->counterDigits[2] > 9999) || (interfaceCtx->counterDigits[2] < 0)) { - interfaceCtx->counterDigits[2] &= 0xDDD; - } + if ((interfaceCtx->counterDigits[2] > 9999) || (interfaceCtx->counterDigits[2] < 0)) { + interfaceCtx->counterDigits[2] &= 0xDDD; + } - while (interfaceCtx->counterDigits[2] >= 100) { - interfaceCtx->counterDigits[0]++; - interfaceCtx->counterDigits[2] -= 100; - } + while (interfaceCtx->counterDigits[2] >= 100) { + interfaceCtx->counterDigits[0]++; + interfaceCtx->counterDigits[2] -= 100; + } - while (interfaceCtx->counterDigits[2] >= 10) { - interfaceCtx->counterDigits[1]++; - interfaceCtx->counterDigits[2] -= 10; - } + while (interfaceCtx->counterDigits[2] >= 10) { + interfaceCtx->counterDigits[1]++; + interfaceCtx->counterDigits[2] -= 10; + } - svar2 = rupeeDigitsFirst[CUR_UPG_VALUE(UPG_WALLET)]; - svar5 = rupeeDigitsCount[CUR_UPG_VALUE(UPG_WALLET)]; + svar2 = rupeeDigitsFirst[CUR_UPG_VALUE(UPG_WALLET)]; + svar5 = rupeeDigitsCount[CUR_UPG_VALUE(UPG_WALLET)]; - // Draw Rupee Counter. Hide in Boss Rush and when not having a wallet in rando. - if (!IS_BOSS_RUSH && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET))) { for (svar1 = 0, svar3 = 16; svar1 < svar5; svar1++, svar2++, svar3 += 8) { OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[svar2]]), 8, 16, PosX_RC + svar3, PosY_RC, 8, 16, 1 << 10, 1 << 10); } } - } - else { + } else { // Make sure item counts have black backgrounds gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->magicAlpha); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0); diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index a825f67d774..b216ce89000 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -341,7 +341,9 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD); Actor_Spawn(&play->actorCtx, play, ACTOR_BG_BREAKWALL, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, 0x6000, true); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -690.0f, -1523.76f, -3304.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -690.0f, -1523.76f, -3304.0f, 0, 0, 0, 0, true); + } } this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; @@ -1832,7 +1834,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { if (this->unk_1DA == 820) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn( &play->actorCtx, play, ACTOR_ITEM_B_HEART, Math_SinS(this->actor.shape.rot.y) * -50.0f + this->actor.world.pos.x, this->actor.world.pos.y, diff --git a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c index 72908fd2f8e..f9d29cf7874 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c @@ -227,7 +227,9 @@ void BossFd_Init(Actor* thisx, PlayState* play) { Actor_Kill(&this->actor); Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 100.0f, 200.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 100.0f, 200.0f, 0, 0, 0, 0, true); + } } else { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_BOSS_FD2, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, this->introState); @@ -913,7 +915,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->actionFunc = BossFd_Wait; this->actor.world.pos.y -= 1000.0f; } - if (this->timers[0] == 7 && !IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, this->timers[0] == 7, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 05740bff9f4..a40a8642993 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -236,8 +236,10 @@ void BossGanondrof_Init(Actor* thisx, PlayState* play) { Actor_Kill(&this->actor); Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 200.0f + GND_BOSSROOM_CENTER_X, - GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 200.0f + GND_BOSSROOM_CENTER_X, + GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z, 0, 0, 0, 0, true); + } } else { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_FHG, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, this->actor.params); @@ -1076,7 +1078,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { this->deathCamera = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z + 200.0f, 0, 0, 0, 0, true); } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index e05b736500c..d8da75ae040 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -341,7 +341,9 @@ void BossGoma_Init(Actor* thisx, PlayState* play) { Actor_Kill(&this->actor); Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -640.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_CHILD); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 141.0f, -640.0f, -84.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 141.0f, -640.0f, -84.0f, 0, 0, 0, 0, true); + } } for (int i = 0; i < ARRAY_COUNT(sClearPixelTex16); i++) { @@ -1118,7 +1120,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) { this->timer = 70; this->decayingProgress = 0; this->subCameraFollowSpeed = 0.0f; - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 7d82b93a48a..00a8c57fe6b 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -372,7 +372,9 @@ void BossMo_Init(Actor* thisx, PlayState* play2) { Actor_Kill(&this->actor); Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -280.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -200.0f, -280.0f, 0.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -200.0f, -280.0f, 0.0f, 0, 0, 0, 0, true); + } play->roomCtx.unk_74[0] = 0xFF; MO_WATER_LEVEL(play) = -500; return; @@ -1120,12 +1122,16 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, this->actor.world.pos.x, -280.0f, this->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 200.0f, - -280.0f, this->actor.world.pos.z, 0, 0, 0, 0, true); } else { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, this->actor.world.pos.x, -280.0f, this->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); } + + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 200.0f, + -280.0f, this->actor.world.pos.z, 0, 0, 0, 0, true); + } + Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR); Flags_SetClear(play, play->roomCtx.curRoom.num); } diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index de754328d7d..8d722013de2 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -295,8 +295,10 @@ void BossSst_Init(Actor* thisx, PlayState* play2) { if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, ROOM_CENTER_Z + 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, ROOM_CENTER_X, ROOM_CENTER_Y, - ROOM_CENTER_Z - 200.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, ROOM_CENTER_X, ROOM_CENTER_Y, + ROOM_CENTER_Z - 200.0f, 0, 0, 0, 0, true); + } Actor_Kill(&this->actor); } else { sHands[LEFT] = @@ -1204,7 +1206,7 @@ void BossSst_HeadFinish(BossSst* this, PlayState* play) { } else if (this->effects[0].alpha == 0) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, ROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, (Math_SinS(this->actor.shape.rot.y) * 200.0f) + ROOM_CENTER_X, ROOM_CENTER_Y, Math_CosS(this->actor.shape.rot.y) * 200.0f + ROOM_CENTER_Z, 0, 0, 0, 0, true); diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 40f8127cd88..661d28fb234 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -2798,11 +2798,15 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { if (!IS_BOSS_RUSH) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -600.0f, 230.f, 0.0f, 0, 0, 0, 0, true); } else { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); } + + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -600.0f, 230.f, 0.0f, 0, 0, 0, 0, true); + } + this->actor.world.pos.y = -2000.0f; this->workf[UNK_F18] = 0.0f; sKoumePtr->visible = sKotakePtr->visible = false; diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 77a497e7a16..14589fdbd62 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -644,8 +644,10 @@ void BossVa_Init(Actor* thisx, PlayState* play2) { Actor_Spawn(&play->actorCtx, play, warpId, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); //! params could be WARP_DUNGEON_CHILD however this can also spawn Ru1 - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 160.0f, - this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 160.0f, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); + } sDoorState = 100; Actor_Kill(&this->actor); } else { @@ -1657,7 +1659,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) { Player_SetCsActionWithHaltedActors(play, &this->actor, 7); sCsState++; - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 29eb6dc94e8..b78963d4397 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -207,11 +207,6 @@ void EnBox_Init(Actor* thisx, PlayState* play2) { if (play->sceneNum == SCENE_FOREST_TEMPLE && this->dyna.actor.params == 10222) { this->movementFlags = ENBOX_MOVE_IMMOBILE; } - - // Delete chests in Boss Rush. Mainly for the chest in King Dodongo's boss room. - if (IS_BOSS_RUSH) { - EnBox_SetupAction(this, EnBox_Destroy); - } } void EnBox_Destroy(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h index 0168fc1a855..088fde9d3b9 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -51,4 +51,9 @@ typedef struct EnBox { /* */ Gfx* boxBodyDL; } EnBox; // size = 0x01FC +// #region SOH [General] Exposed these functions for use in other places (Boss Rush as an example) +void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc); +void EnBox_Destroy(Actor* thisx, PlayState* play); +// #endregion + #endif diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index 04b0ca1e31c..a0e529991fa 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -277,11 +277,6 @@ void EnKusa_Destroy(Actor* thisx, PlayState* play2) { } void EnKusa_SetupWaitObject(EnKusa* this) { - // Kill bushes in Boss Rush. Used in Gohma's arena. - if (IS_BOSS_RUSH) { - Actor_Kill(this); - } - EnKusa_SetupAction(this, EnKusa_WaitObject); } diff --git a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c index 0dd03a5bef9..9be71e91b0c 100644 --- a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c +++ b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c @@ -221,11 +221,6 @@ void ObjTsubo_WaterBreak(ObjTsubo* this, PlayState* play) { } void ObjTsubo_SetupWaitForObject(ObjTsubo* this) { - // Remove pots in Boss Rush. Present in Barinade's and Ganondorf's arenas. - if (IS_BOSS_RUSH) { - Actor_Kill(this); - } - this->actionFunc = ObjTsubo_WaitForObject; } From b8b5644a6338f3f0f026a3661826bf6a6e7e0b17 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 25 Jul 2024 22:15:17 +0200 Subject: [PATCH 03/48] Move BossRush_HandleCompleteBoss to VB --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 25 +++++++++++-------- .../game-interactor/GameInteractor.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 7 ++++++ .../game-interactor/GameInteractor_Hooks.h | 1 + soh/src/code/z_horse.c | 1 + .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 3 +-- .../overlays/actors/ovl_Boss_Fd/z_boss_fd.c | 1 + .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 3 +-- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 4 +-- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 3 +-- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 3 +-- .../actors/ovl_Boss_Goma/z_boss_goma.c | 4 +-- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 4 +-- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 4 +-- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 4 +-- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 4 +-- soh/src/overlays/actors/ovl_En_Box/z_en_box.h | 5 ---- 17 files changed, 42 insertions(+), 35 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index e62782bac23..b0247278fff 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -1,15 +1,17 @@ #include "BossRush.h" #include "soh/OTRGlobals.h" -#include "functions.h" -#include "macros.h" -#include "variables.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #include #include extern "C" { - #include "src/overlays/actors/ovl_En_Box/z_en_box.h" + #include "functions.h" + #include "macros.h" + #include "variables.h" + extern PlayState* gPlayState; } typedef struct BossRushSetting { @@ -505,14 +507,9 @@ void BossRush_OnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); // Remove chests in Boss Rush. Mainly for the chest in King Dodongo's boss room. - if (actor->id == ACTOR_EN_BOX) { - EnBox_SetupAction(actor, EnBox_Destroy); - return; - } - // Remove bushes in Boss Rush. Used in Gohma's arena. // Remove pots in Boss Rush. Used in Barinade's and Ganondorf's arenas. - if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO) { + if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) { Actor_Kill(actor); return; } @@ -525,24 +522,32 @@ void BossRush_OnSceneInitHandler(int16_t sceneNum) { } } +void BossRush_OnBossDefeatHandler(void* refActor) { + BossRush_HandleCompleteBoss(gPlayState); +} + void BossRush_RegisterHooks() { static uint32_t onVanillaBehaviorHook = 0; static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; + static uint32_t onBossDefeatHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(onBossDefeatHook); onVanillaBehaviorHook = 0; onSceneInitHook = 0; onActorInitHook = 0; + onBossDefeatHook = 0; if (!IS_BOSS_RUSH) return; onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnVanillaBehaviorHandler); onSceneInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); + onBossDefeatHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnBossDefeatHandler); }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 97601d540d1..6372fbf7a03 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -700,6 +700,7 @@ class GameInteractor { DEFINE_HOOK(OnActorUpdate, (void* actor)); DEFINE_HOOK(OnActorKill, (void* actor)); DEFINE_HOOK(OnEnemyDefeat, (void* actor)); + DEFINE_HOOK(OnBossDefeat, (void* actor)); DEFINE_HOOK(OnPlayerBonk, ()); DEFINE_HOOK(OnPlayDestroy, ()); DEFINE_HOOK(OnPlayDrawEnd, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 93c8fc75eba..49724b66cf2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -100,6 +100,13 @@ void GameInteractor_ExecuteOnEnemyDefeat(void* actor) { GameInteractor::Instance->ExecuteHooksForFilter(actor); } +void GameInteractor_ExecuteOnBossDefeat(void* actor) { + GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); +} + void GameInteractor_ExecuteOnPlayerBonk() { GameInteractor::Instance->ExecuteHooks(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 82deeaf8020..e1cba237db1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -22,6 +22,7 @@ void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor); void GameInteractor_ExecuteOnEnemyDefeat(void* actor); +void GameInteractor_ExecuteOnBossDefeat(void* actor); void GameInteractor_ExecuteOnPlayerBonk(); void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); diff --git a/soh/src/code/z_horse.c b/soh/src/code/z_horse.c index 1f242232eea..d72b80396a8 100644 --- a/soh/src/code/z_horse.c +++ b/soh/src/code/z_horse.c @@ -1,6 +1,7 @@ #include "global.h" #include "vt.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor.h" s32 func_8006CFC0(s32 scene) { s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS, SCENE_LON_LON_RANCH }; diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index b216ce89000..8a1635f6c51 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -4,7 +4,6 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include // malloc @@ -1549,7 +1548,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { this->cameraAt.y = camera->at.y; this->cameraAt.z = camera->at.z; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); break; case 5: tempSin = Math_SinS(this->actor.shape.rot.y - 0x1388) * 150.0f; diff --git a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c index f9d29cf7874..f24174fbc7c 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c @@ -14,6 +14,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index 2a03f1839e4..b38908a5e42 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -10,7 +10,6 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -900,7 +899,7 @@ void BossFd2_CollisionCheck(BossFd2* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); } else if (damage) { BossFd2_SetupDamaged(this, play); this->work[FD2_DAMAGE_FLASH_TIMER] = 10; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 145fdcfd9e9..39031bcf7e5 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -11,7 +11,7 @@ #include "assets/scenes/dungeons/ganon_boss/ganon_boss_scene.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/boss-rush/BossRushTypes.h" #include @@ -2807,7 +2807,7 @@ void BossGanon_UpdateDamage(BossGanon* this, PlayState* play) { Audio_QueueSeqCmd(0x100100FF); this->screenFlashTimer = 4; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DAMAGE2); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_CUTBODY); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index d9dd602c5d5..3afc234f075 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -7,7 +7,6 @@ #include "objects/object_ganon_anime3/object_ganon_anime3.h" #include "objects/object_geff/object_geff.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #include @@ -1689,7 +1688,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { (player->meleeWeaponState != 0) && (player->heldItemAction == PLAYER_IA_SWORD_MASTER)) { func_80064520(play, &play->csCtx); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); gSaveContext.sohStats.gameComplete = true; this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index a40a8642993..e36b7905729 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -11,7 +11,6 @@ #include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -1222,7 +1221,7 @@ void BossGanondrof_CollisionCheck(BossGanondrof* this, PlayState* play) { BossGanondrof_SetupDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index d8da75ae040..c598dfcf318 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -4,7 +4,7 @@ #include "overlays/actors/ovl_En_Goma/z_en_goma.h" #include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -1844,7 +1844,7 @@ void BossGoma_UpdateHit(BossGoma* this, PlayState* play) { BossGoma_SetupDefeated(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); } this->invincibilityFrames = 10; diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 00a8c57fe6b..fbc899f2668 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -12,7 +12,7 @@ #include "vt.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #include @@ -1800,7 +1800,7 @@ void BossMo_CoreCollisionCheck(BossMo* this, PlayState* play) { ((sMorphaTent1->csCamera == 0) && (sMorphaTent2 != NULL) && (sMorphaTent2->csCamera == 0))) { Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->csState = MO_DEATH_START; sMorphaTent1->drawActor = false; diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 8d722013de2..f3c706380e2 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -11,7 +11,7 @@ #include "overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) @@ -2566,7 +2566,7 @@ void BossSst_HeadCollisionCheck(BossSst* this, PlayState* play) { Enemy_StartFinishingBlow(play, &this->actor); BossSst_HeadSetupDeath(this, play); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); } else { BossSst_HeadSetupDamage(this); } diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 661d28fb234..b7c400c1bfc 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -4,7 +4,7 @@ #include "objects/object_tw/object_tw.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #include @@ -5294,7 +5294,7 @@ void BossTw_TwinrovaDamage(BossTw* this, PlayState* play, u8 damage) { Enemy_StartFinishingBlow(play, &this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_YOUNG_DEAD); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 14589fdbd62..7c827add015 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -15,7 +15,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -1404,7 +1404,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) { BossVa_SetupBodyDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; - BossRush_HandleCompleteBoss(play); + GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } this->actor.speedXZ = -10.0f; diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h index 088fde9d3b9..0168fc1a855 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -51,9 +51,4 @@ typedef struct EnBox { /* */ Gfx* boxBodyDL; } EnBox; // size = 0x01FC -// #region SOH [General] Exposed these functions for use in other places (Boss Rush as an example) -void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc); -void EnBox_Destroy(Actor* thisx, PlayState* play); -// #endregion - #endif From d675284096acab12515b8739312e41bcc3089a0c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 25 Jul 2024 22:35:20 +0200 Subject: [PATCH 04/48] Convert boss timestamps to VB --- soh/soh/Enhancements/mods.cpp | 42 ++++++++++++++++++- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 1 - .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 1 - .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 1 - .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 2 - .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 1 - .../actors/ovl_Boss_Goma/z_boss_goma.c | 1 - .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 1 - .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 1 - .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 1 - .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 1 - 11 files changed, 41 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index af21f540bb4..b025559be10 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -872,7 +872,7 @@ static std::unordered_map uniqueEnemyIdToStatCount = { void RegisterEnemyDefeatCounts() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { - Actor* actor = (Actor*)refActor; + Actor* actor = static_cast(refActor); if (uniqueEnemyIdToStatCount.contains(actor->id)) { gSaveContext.sohStats.count[uniqueEnemyIdToStatCount[actor->id]]++; } else { @@ -1016,6 +1016,45 @@ void RegisterEnemyDefeatCounts() { }); } +void RegisterBossDefeatTimestamps() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + Actor* actor = static_cast(refActor); + switch (actor->id) { + case ACTOR_BOSS_DODONGO: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_FD2: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GANON: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GANON2: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + break; + case ACTOR_BOSS_GANONDROF: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GOMA: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_MO: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_SST: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_TW: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_VA: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; + break; + } + }); +} + typedef enum { ADD_ICE_TRAP, ADD_BURN_TRAP, @@ -1806,6 +1845,7 @@ void InitMods() { RegisterTriforceHunt(); RegisterGrantGanonsBossKey(); RegisterEnemyDefeatCounts(); + RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); RegisterRandomizerSheikSpawn(); RegisterBossSouls(); diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index 8a1635f6c51..599eb7a0937 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -1547,7 +1547,6 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { this->cameraAt.x = camera->at.x; this->cameraAt.y = camera->at.y; this->cameraAt.z = camera->at.z; - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); break; case 5: diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index b38908a5e42..6a996ebd05d 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -898,7 +898,6 @@ void BossFd2_CollisionCheck(BossFd2* this, PlayState* play) { Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); } else if (damage) { BossFd2_SetupDamaged(this, play); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 39031bcf7e5..f1ef4975f53 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -2806,7 +2806,6 @@ void BossGanon_UpdateDamage(BossGanon* this, PlayState* play) { func_80078914(&sZeroVec, NA_SE_EN_LAST_DAMAGE); Audio_QueueSeqCmd(0x100100FF); this->screenFlashTimer = 4; - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DAMAGE2); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 3afc234f075..a63deb7d388 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -1687,9 +1687,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { if ((ABS(temp_a0_2) < 0x2000) && (sqrtf(SQ(temp_f14) + SQ(temp_f12)) < 70.0f) && (player->meleeWeaponState != 0) && (player->heldItemAction == PLAYER_IA_SWORD_MASTER)) { func_80064520(play, &play->csCtx); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); - gSaveContext.sohStats.gameComplete = true; this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index e36b7905729..4dd352eb711 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -1220,7 +1220,6 @@ void BossGanondrof_CollisionCheck(BossGanondrof* this, PlayState* play) { if ((s8)this->actor.colChkInfo.health <= 0) { BossGanondrof_SetupDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index c598dfcf318..32c5aef5398 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -1843,7 +1843,6 @@ void BossGoma_UpdateHit(BossGoma* this, PlayState* play) { } else { BossGoma_SetupDefeated(this, play); Enemy_StartFinishingBlow(play, &this->actor); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index fbc899f2668..c4e664e90ee 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -1799,7 +1799,6 @@ void BossMo_CoreCollisionCheck(BossMo* this, PlayState* play) { if (((sMorphaTent1->csCamera == 0) && (sMorphaTent2 == NULL)) || ((sMorphaTent1->csCamera == 0) && (sMorphaTent2 != NULL) && (sMorphaTent2->csCamera == 0))) { Enemy_StartFinishingBlow(play, &this->actor); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->csState = MO_DEATH_START; diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index f3c706380e2..7b61e408895 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -2565,7 +2565,6 @@ void BossSst_HeadCollisionCheck(BossSst* this, PlayState* play) { if (Actor_ApplyDamage(&this->actor) == 0) { Enemy_StartFinishingBlow(play, &this->actor); BossSst_HeadSetupDeath(this, play); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); } else { BossSst_HeadSetupDamage(this); diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index b7c400c1bfc..089b703ad96 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -5293,7 +5293,6 @@ void BossTw_TwinrovaDamage(BossTw* this, PlayState* play, u8 damage) { BossTw_TwinrovaSetupDeathCS(this, play); Enemy_StartFinishingBlow(play, &this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_YOUNG_DEAD); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 7c827add015..6b65c73a367 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -1403,7 +1403,6 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) { if (sFightPhase >= PHASE_DEATH) { BossVa_SetupBodyDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; GameInteractor_ExecuteOnBossDefeat(&this->actor); return; } From 5368b19bc3adeef02731e8ef2b58ca2b9341e68c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 25 Jul 2024 22:52:47 +0200 Subject: [PATCH 05/48] Move being able to open doors to VB --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 10 ++++++---- soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/src/overlays/actors/ovl_player_actor/z_player.c | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index b0247278fff..b5ab7b2141f 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -496,6 +496,8 @@ void BossRush_SetEquipment(uint8_t linkAge) { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + // Disable doors so the player can't leave the boss rooms backwards. + case VB_BE_ABLE_TO_OPEN_DOORS: case VB_SPAWN_HEART_CONTAINER: case VB_RENDER_RUPEE_COUNTER: *should = false; @@ -506,9 +508,9 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* void BossRush_OnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); - // Remove chests in Boss Rush. Mainly for the chest in King Dodongo's boss room. - // Remove bushes in Boss Rush. Used in Gohma's arena. - // Remove pots in Boss Rush. Used in Barinade's and Ganondorf's arenas. + // Remove chests, mainly for the chest in King Dodongo's boss room. + // Remove bushes, used in Gohma's arena. + // Remove pots, used in Barinade's and Ganondorf's arenas. if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) { Actor_Kill(actor); return; @@ -516,7 +518,7 @@ void BossRush_OnActorInitHandler(void* actorRef) { } void BossRush_OnSceneInitHandler(int16_t sceneNum) { - // Unpause the timer for Boss Rush when the scene loaded isn't the Chamber of Sages. + // Unpause the timer when the scene loaded isn't the Chamber of Sages. if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { gSaveContext.isBossRushPaused = 0; } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 6372fbf7a03..83416a62e72 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -260,6 +260,8 @@ typedef enum { VB_RENDER_KEY_COUNTER, // Vanilla condition: true VB_SPAWN_HEART_CONTAINER, + // Vanilla condition: true + VB_BE_ABLE_TO_OPEN_DOORS, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 3dfb2dbeba9..397c5a5960e 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -4844,8 +4844,7 @@ s32 Player_ActionChange_1(Player* this, PlayState* play) { if ((this->doorType != PLAYER_DOORTYPE_NONE) && (!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) || ((this->heldActor != NULL) && (this->heldActor->id == ACTOR_EN_RU1)))) { - // Disable doors in Boss Rush so the player can't leave the boss rooms backwards. - if ((CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (Player_Action_8084F9A0 == this->actionFunc)) && !IS_BOSS_RUSH) { + if ((CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (Player_Action_8084F9A0 == this->actionFunc)) && GameInteractor_Should(VB_BE_ABLE_TO_OPEN_DOORS, true, NULL)) { doorActor = this->doorActor; if (this->doorType <= PLAYER_DOORTYPE_AJAR) { From 103b8c28fdaa9067ae0d905550898629bc160f92 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:10:30 +0200 Subject: [PATCH 06/48] Convert Entrance_OverrideWeatherState to VB --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 4 ++++ soh/src/code/z_play.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 78cdd1a32dc..6cced1225df 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1252,6 +1252,10 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->MarkAsNotObtained(); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { + Entrance_OverrideWeatherState(); + } + // LACs & Prelude checks static uint32_t updateHook = 0; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index a54314d0027..56c7868891e 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1804,10 +1804,6 @@ void* Play_LoadFile(PlayState* play, RomFile* file) { } void Play_InitEnvironment(PlayState* play, s16 skyboxId) { - // For entrance rando, ensure the correct weather state and sky mode is applied - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Entrance_OverrideWeatherState(); - } Skybox_Init(&play->state, &play->skyboxCtx, skyboxId); Environment_Init(play, &play->envCtx, 0); } From fb01c9e8a2cf6bf8cf09fbbc2c693047645e57f2 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:17:00 +0200 Subject: [PATCH 07/48] Move boss souls to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 58 ------------------- .../Enhancements/randomizer/hook_handlers.cpp | 53 +++++++++++++++++ 2 files changed, 53 insertions(+), 58 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index b025559be10..348405f5419 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1223,63 +1223,6 @@ void RegisterRandomizerSheikSpawn() { }); } -//Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair -void RegisterBossSouls() { - GameInteractor::Instance->RegisterGameHook([](void* actor) { - if (!gPlayState) return; - if (!IS_RANDO || !(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS))) return; - RandomizerInf rand_inf = RAND_INF_MAX; - Actor* actual = (Actor*)actor; - switch (gPlayState->sceneNum){ - case SCENE_DEKU_TREE_BOSS: - rand_inf = RAND_INF_GOHMA_SOUL; - break; - case SCENE_DODONGOS_CAVERN_BOSS: - rand_inf = RAND_INF_KING_DODONGO_SOUL; - break; - case SCENE_JABU_JABU_BOSS: - rand_inf = RAND_INF_BARINADE_SOUL; - break; - case SCENE_FOREST_TEMPLE_BOSS: - rand_inf = RAND_INF_PHANTOM_GANON_SOUL; - break; - case SCENE_FIRE_TEMPLE_BOSS: - rand_inf = RAND_INF_VOLVAGIA_SOUL; - break; - case SCENE_WATER_TEMPLE_BOSS: - rand_inf = RAND_INF_MORPHA_SOUL; - break; - case SCENE_SHADOW_TEMPLE_BOSS: - rand_inf = RAND_INF_BONGO_BONGO_SOUL; - break; - case SCENE_SPIRIT_TEMPLE_BOSS: - rand_inf = RAND_INF_TWINROVA_SOUL; - break; - case SCENE_GANONDORF_BOSS: - case SCENE_GANON_BOSS: - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS) == RO_BOSS_SOULS_ON_PLUS_GANON) { - rand_inf = RAND_INF_GANON_SOUL; - } - break; - default: break; - } - - //Deletes all actors in the boss category if the soul isn't found. - //Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual bosses, - //so ignore any "boss" if `rand_inf` doesn't change from RAND_INF_MAX. - if (rand_inf != RAND_INF_MAX) { - if (!Flags_GetRandomizerInf(rand_inf) && actual->category == ACTORCAT_BOSS) { - Actor_Delete(&gPlayState->actorCtx, actual, gPlayState); - } - //Special case for Phantom Ganon's horse (and fake), as they're considered "background actors", - //but still control the boss fight flow. - if (!Flags_GetRandomizerInf(RAND_INF_PHANTOM_GANON_SOUL) && actual->id == ACTOR_EN_FHG) { - Actor_Delete(&gPlayState->actorCtx, actual, gPlayState); - } - } - }); -} - void UpdateHurtContainerModeState(bool newState) { static bool hurtEnabled = false; if (hurtEnabled == newState) { @@ -1848,7 +1791,6 @@ void InitMods() { RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); RegisterRandomizerSheikSpawn(); - RegisterBossSouls(); RegisterRandomizedEnemySizes(); RegisterOpenAllHours(); RegisterToTMedallions(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 6cced1225df..254903d347f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1545,6 +1545,59 @@ void RandomizerOnActorInitHandler(void* actorRef) { ) { Actor_Kill(actor); } + + if (RAND_GET_OPTION(RSK_SHUFFLE_BOSS_SOULS)) { + //Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair + RandomizerInf currentBossSoulRandInf = RAND_INF_MAX; + switch (gPlayState->sceneNum){ + case SCENE_DEKU_TREE_BOSS: + currentBossSoulRandInf = RAND_INF_GOHMA_SOUL; + break; + case SCENE_DODONGOS_CAVERN_BOSS: + currentBossSoulRandInf = RAND_INF_KING_DODONGO_SOUL; + break; + case SCENE_JABU_JABU_BOSS: + currentBossSoulRandInf = RAND_INF_BARINADE_SOUL; + break; + case SCENE_FOREST_TEMPLE_BOSS: + currentBossSoulRandInf = RAND_INF_PHANTOM_GANON_SOUL; + break; + case SCENE_FIRE_TEMPLE_BOSS: + currentBossSoulRandInf = RAND_INF_VOLVAGIA_SOUL; + break; + case SCENE_WATER_TEMPLE_BOSS: + currentBossSoulRandInf = RAND_INF_MORPHA_SOUL; + break; + case SCENE_SHADOW_TEMPLE_BOSS: + currentBossSoulRandInf = RAND_INF_BONGO_BONGO_SOUL; + break; + case SCENE_SPIRIT_TEMPLE_BOSS: + currentBossSoulRandInf = RAND_INF_TWINROVA_SOUL; + break; + case SCENE_GANONDORF_BOSS: + case SCENE_GANON_BOSS: + if (RAND_GET_OPTION(RSK_SHUFFLE_BOSS_SOULS) == RO_BOSS_SOULS_ON_PLUS_GANON) { + currentBossSoulRandInf = RAND_INF_GANON_SOUL; + } + break; + default: + break; + } + + //Deletes all actors in the boss category if the soul isn't found. + //Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual bosses, + //so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX. + if (currentBossSoulRandInf != RAND_INF_MAX) { + if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS) { + Actor_Delete(&gPlayState->actorCtx, actor, gPlayState); + } + //Special case for Phantom Ganon's horse (and fake), as they're considered "background actors", + //but still control the boss fight flow. + if (!Flags_GetRandomizerInf(RAND_INF_PHANTOM_GANON_SOUL) && actor->id == ACTOR_EN_FHG) { + Actor_Delete(&gPlayState->actorCtx, actor, gPlayState); + } + } + } } void RandomizerRegisterHooks() { From e486bf848a1de5887f61c608f6d4144a1ada892c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:19:32 +0200 Subject: [PATCH 08/48] Update hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 254903d347f..f7af53b64d0 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1252,7 +1252,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->MarkAsNotObtained(); } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { + if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { Entrance_OverrideWeatherState(); } From 77f0be16ba71cc7aef769bbf7fce2f4534d9d88c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:33:05 +0200 Subject: [PATCH 09/48] Move infinite upgrades to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 41 ------------------- .../Enhancements/randomizer/hook_handlers.cpp | 38 +++++++++++++++++ 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 348405f5419..7b8e6945363 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1676,46 +1676,6 @@ void RegisterFishsanity() { }); } -void RegisterInfiniteUpgrades() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!IS_RANDO) { - return; - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER)) { - AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER); - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG)) { - AMMO(ITEM_BOMB) = CUR_CAPACITY(UPG_BOMB_BAG); - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG)) { - AMMO(ITEM_SLINGSHOT) = CUR_CAPACITY(UPG_BULLET_BAG); - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE)) { - AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE)) { - AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER)) { - gSaveContext.magic = gSaveContext.magicCapacity; - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS)) { - AMMO(ITEM_BOMBCHU) = 50; - } - - if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) { - gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET); - } - }); -} - extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); void PatchCompasses() { @@ -1797,7 +1757,6 @@ void InitMods() { RegisterNoSwim(); RegisterNoWallet(); RegisterFishsanity(); - RegisterInfiniteUpgrades(); RegisterRandomizerCompasses(); NameTag_RegisterHooks(); RegisterFloorSwitchesHook(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f7af53b64d0..ffad9b47fcd 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1600,6 +1600,40 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } +void RandomizerOnGameFrameUpdateHandler() { + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER)) { + AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER); + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG)) { + AMMO(ITEM_BOMB) = CUR_CAPACITY(UPG_BOMB_BAG); + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG)) { + AMMO(ITEM_SLINGSHOT) = CUR_CAPACITY(UPG_BULLET_BAG); + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE)) { + AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE)) { + AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER)) { + gSaveContext.magic = gSaveContext.magicCapacity; + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS)) { + AMMO(ITEM_BOMBCHU) = 50; + } + + if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) { + gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET); + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -1609,6 +1643,7 @@ void RandomizerRegisterHooks() { static uint32_t onVanillaBehaviorHook = 0; static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; + static uint32_t onGameFrameUpdateHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { randomizerQueuedChecks = std::queue(); @@ -1623,6 +1658,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdateHook); onFlagSetHook = 0; onSceneFlagSetHook = 0; @@ -1632,6 +1668,7 @@ void RandomizerRegisterHooks() { onVanillaBehaviorHook = 0; onSceneInitHook = 0; onActorInitHook = 0; + onGameFrameUpdateHook = 0; if (!IS_RANDO) return; @@ -1643,5 +1680,6 @@ void RandomizerRegisterHooks() { onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); + onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); }); } From 2f0c4ed591aa1973a47d76e8d0215c13aff5877c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:36:00 +0200 Subject: [PATCH 10/48] Move skeleton key to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 19 ------------------ .../Enhancements/randomizer/hook_handlers.cpp | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 7b8e6945363..949b26784cd 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1696,24 +1696,6 @@ void RegisterRandomizerCompasses() { }); } -void RegisterSkeletonKey() { - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - Actor* actor = static_cast(refActor); - - if (Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { - if (actor->id == ACTOR_EN_DOOR) { - EnDoor* door = (EnDoor*)actor; - door->lockTimer = 0; - } else if (actor->id == ACTOR_DOOR_SHUTTER) { - DoorShutter* shutterDoor = (DoorShutter*)actor; - if (shutterDoor->doorType == SHUTTER_KEY_LOCKED) { - shutterDoor->unk_16E = 0; - } - } - } - }); -} - void InitMods() { BossRush_RegisterHooks(); RandomizerRegisterHooks(); @@ -1763,5 +1745,4 @@ void InitMods() { RegisterPatchHandHandler(); RegisterHurtContainerModeHandler(); RegisterPauseMenuHooks(); - RegisterSkeletonKey(); } diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ffad9b47fcd..5dbb62c6f64 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1634,6 +1634,22 @@ void RandomizerOnGameFrameUpdateHandler() { } } +void RandomizerOnActorUpdateHandler(void* refActor) { + Actor* actor = static_cast(refActor); + + if (Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY)) { + if (actor->id == ACTOR_EN_DOOR) { + EnDoor* door = reinterpret_cast(actor); + door->lockTimer = 0; + } else if (actor->id == ACTOR_DOOR_SHUTTER) { + DoorShutter* shutterDoor = reinterpret_cast(actor); + if (shutterDoor->doorType == SHUTTER_KEY_LOCKED) { + shutterDoor->unk_16E = 0; + } + } + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -1643,6 +1659,7 @@ void RandomizerRegisterHooks() { static uint32_t onVanillaBehaviorHook = 0; static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; + static uint32_t onActorUpdateHook = 0; static uint32_t onGameFrameUpdateHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { @@ -1658,6 +1675,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(onActorUpdateHook); GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdateHook); onFlagSetHook = 0; @@ -1668,6 +1686,7 @@ void RandomizerRegisterHooks() { onVanillaBehaviorHook = 0; onSceneInitHook = 0; onActorInitHook = 0; + onActorUpdateHook = 0; onGameFrameUpdateHook = 0; if (!IS_RANDO) return; @@ -1680,6 +1699,7 @@ void RandomizerRegisterHooks() { onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); + onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); }); } From 8b2399ab91cd7b5466a31ce9bb758c17aabdcf64 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:43:35 +0200 Subject: [PATCH 11/48] Move swim and child wallet to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 87 ------------------- .../Enhancements/randomizer/hook_handlers.cpp | 84 ++++++++++++++++++ 2 files changed, 84 insertions(+), 87 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 949b26784cd..cdb1de42607 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1441,91 +1441,6 @@ void RegisterPauseMenuHooks() { }); } -//from z_player.c -typedef struct { - /* 0x00 */ Vec3f pos; - /* 0x0C */ s16 yaw; -} SpecialRespawnInfo; // size = 0x10 - -//special respawns used when voided out without swim to prevent infinite loops -std::map swimSpecialRespawnInfo = { - { - ENTR_ZORAS_RIVER_3,//hf to zr in water - { { -1455.443, -20, 1384.826 }, 28761 } - }, - { - ENTR_HYRULE_FIELD_14,//zr to hf in water - { { 5830.209, -92.16, 3925.911 }, -20025 } - }, - { - ENTR_LOST_WOODS_7,//zr to lw - { { 1978.718, -36.908, -855 }, -16384 } - }, - { - ENTR_ZORAS_RIVER_4,//lw to zr - { { 4082.366, 860.442, -1018.949 }, -32768 } - }, - { - ENTR_LAKE_HYLIA_1,//gv to lh - { { -3276.416, -1033, 2908.421 }, 11228 } - }, - { - ENTR_WATER_TEMPLE_0,//lh to water temple - { { -182, 780, 759.5 }, -32768 } - }, - { - ENTR_LAKE_HYLIA_2,//water temple to lh - { { -955.028, -1306.9, 6768.954 }, -32768 } - }, - { - ENTR_ZORAS_DOMAIN_4,//lh to zd - { { -109.86, 11.396, -9.933 }, -29131 } - }, - { - ENTR_LAKE_HYLIA_7,//zd to lh - { { -912, -1326.967, 3391 }, 0 } - }, - { - ENTR_GERUDO_VALLEY_1,//caught by gerudos as child - { { -424, -2051, -74 }, 16384 } - } -}; - -void RegisterNoSwim() { - GameInteractor::Instance->RegisterGameHook([]() { - if ( - IS_RANDO && - (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && - !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && - CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON - ) { - //if you void out in water temple without swim you get instantly kicked out to prevent softlocks - if (gPlayState->sceneNum == SCENE_WATER_TEMPLE) { - GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_2));//lake hylia from water temple - return; - } - - if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { - SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); - - Play_SetupRespawnPoint(gPlayState, RESPAWN_MODE_DOWN, 0xDFF); - gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = respawnInfo->pos; - gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw; - } - - Play_TriggerVoidOut(gPlayState); - } - }); -} - -void RegisterNoWallet() { - GameInteractor::Instance->RegisterGameHook([]() { - if (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) { - gSaveContext.rupees = 0; - } - }); -} - void RegisterFishsanity() { static s16 fishGroupCounter = 0; @@ -1736,8 +1651,6 @@ void InitMods() { RegisterRandomizedEnemySizes(); RegisterOpenAllHours(); RegisterToTMedallions(); - RegisterNoSwim(); - RegisterNoWallet(); RegisterFishsanity(); RegisterRandomizerCompasses(); NameTag_RegisterHooks(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 5dbb62c6f64..0df7ee1bc1e 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -33,6 +33,8 @@ extern "C" { #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" #include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" +#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "adult_trade_shuffle.h" #include "draw.h" @@ -1632,6 +1634,10 @@ void RandomizerOnGameFrameUpdateHandler() { if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) { gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET); } + + if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) { + gSaveContext.rupees = 0; + } } void RandomizerOnActorUpdateHandler(void* refActor) { @@ -1650,6 +1656,80 @@ void RandomizerOnActorUpdateHandler(void* refActor) { } } +//from z_player.c +typedef struct { + /* 0x00 */ Vec3f pos; + /* 0x0C */ s16 yaw; +} SpecialRespawnInfo; // size = 0x10 + +//special respawns used when voided out without swim to prevent infinite loops +std::map swimSpecialRespawnInfo = { + { + ENTR_ZORAS_RIVER_3,//hf to zr in water + { { -1455.443, -20, 1384.826 }, 28761 } + }, + { + ENTR_HYRULE_FIELD_14,//zr to hf in water + { { 5830.209, -92.16, 3925.911 }, -20025 } + }, + { + ENTR_LOST_WOODS_7,//zr to lw + { { 1978.718, -36.908, -855 }, -16384 } + }, + { + ENTR_ZORAS_RIVER_4,//lw to zr + { { 4082.366, 860.442, -1018.949 }, -32768 } + }, + { + ENTR_LAKE_HYLIA_1,//gv to lh + { { -3276.416, -1033, 2908.421 }, 11228 } + }, + { + ENTR_WATER_TEMPLE_0,//lh to water temple + { { -182, 780, 759.5 }, -32768 } + }, + { + ENTR_LAKE_HYLIA_2,//water temple to lh + { { -955.028, -1306.9, 6768.954 }, -32768 } + }, + { + ENTR_ZORAS_DOMAIN_4,//lh to zd + { { -109.86, 11.396, -9.933 }, -29131 } + }, + { + ENTR_LAKE_HYLIA_7,//zd to lh + { { -912, -1326.967, 3391 }, 0 } + }, + { + ENTR_GERUDO_VALLEY_1,//caught by gerudos as child + { { -424, -2051, -74 }, 16384 } + } +}; + +void RandomizerOnPlayerUpdateHandler() { + if ( + (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && + !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && + CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON + ) { + //if you void out in water temple without swim you get instantly kicked out to prevent softlocks + if (gPlayState->sceneNum == SCENE_WATER_TEMPLE) { + GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_2));//lake hylia from water temple + return; + } + + if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { + SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); + + Play_SetupRespawnPoint(gPlayState, RESPAWN_MODE_DOWN, 0xDFF); + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = respawnInfo->pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw; + } + + Play_TriggerVoidOut(gPlayState); + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -1660,6 +1740,7 @@ void RandomizerRegisterHooks() { static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; static uint32_t onActorUpdateHook = 0; + static uint32_t onPlayerUpdateHook = 0; static uint32_t onGameFrameUpdateHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { @@ -1676,6 +1757,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); GameInteractor::Instance->UnregisterGameHook(onActorUpdateHook); + GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateHook); GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdateHook); onFlagSetHook = 0; @@ -1687,6 +1769,7 @@ void RandomizerRegisterHooks() { onSceneInitHook = 0; onActorInitHook = 0; onActorUpdateHook = 0; + onPlayerUpdateHook = 0; onGameFrameUpdateHook = 0; if (!IS_RANDO) return; @@ -1700,6 +1783,7 @@ void RandomizerRegisterHooks() { onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); + onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); }); } From 54f9c7f2d2d9abee6efbae2dfda92b755597f57d Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:48:56 +0200 Subject: [PATCH 12/48] Move ganons boss key to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 14 -------------- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index cdb1de42607..8beedd26a07 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -812,19 +812,6 @@ void RegisterTriforceHunt() { }); } -void RegisterGrantGanonsBossKey() { - GameInteractor::Instance->RegisterGameHook([]() { - // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. - if (!GameInteractor::IsGameplayPaused() && IS_RANDO && - Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && gPlayState->transitionTrigger != TRANS_TRIGGER_START && - (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { - GetItemEntry getItemEntry = - ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); - GiveItemEntryWithoutActor(gPlayState, getItemEntry); - } - }); -} - //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -1643,7 +1630,6 @@ void InitMods() { RegisterMirrorModeHandler(); RegisterResetNaviTimer(); RegisterTriforceHunt(); - RegisterGrantGanonsBossKey(); RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 0df7ee1bc1e..fa1e2271172 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2,6 +2,7 @@ #include "soh/OTRGlobals.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" +#include "soh/Enhancements/item-tables/ItemTableManager.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/dungeon.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -1728,6 +1729,16 @@ void RandomizerOnPlayerUpdateHandler() { Play_TriggerVoidOut(gPlayState); } + + // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. + if ( + !GameInteractor::IsGameplayPaused() && + Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && + gPlayState->transitionTrigger != TRANS_TRIGGER_START && + (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0 + ) { + GiveItemEntryWithoutActor(gPlayState, ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY)); + } } void RandomizerRegisterHooks() { From d5950dde68f6d980455a9ba50552065fd1c22abb Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:55:13 +0200 Subject: [PATCH 13/48] Move triforce hunt to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 30 ------------------- .../Enhancements/randomizer/hook_handlers.cpp | 26 ++++++++++++++++ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 8beedd26a07..0390b6e791c 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -783,35 +783,6 @@ void RegisterResetNaviTimer() { }); } -f32 triforcePieceScale; - -void RegisterTriforceHunt() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsGameplayPaused() && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) { - - // Warp to credits - if (GameInteractor::State::TriforceHuntCreditsWarpActive) { - gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0xFFF2; - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; - GameInteractor::State::TriforceHuntCreditsWarpActive = 0; - } - - // Reset Triforce Piece scale for GI animation. Triforce Hunt allows for multiple triforce models, - // and cycles through them based on the amount of triforce pieces collected. It takes a little while - // for the count to increase during the GI animation, so the model is entirely hidden until that piece - // has been added. That scale has to be reset after the textbox is closed, and this is the best way - // to ensure it's done at that point in time specifically. - if (GameInteractor::State::TriforceHuntPieceGiven) { - triforcePieceScale = 0.0f; - GameInteractor::State::TriforceHuntPieceGiven = 0; - } - } - }); -} - //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -1629,7 +1600,6 @@ void InitMods() { RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); - RegisterTriforceHunt(); RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index fa1e2271172..a64ba0b6473 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1707,6 +1707,8 @@ std::map swimSpecialRespawnInfo = { } }; +f32 triforcePieceScale; + void RandomizerOnPlayerUpdateHandler() { if ( (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && @@ -1739,6 +1741,30 @@ void RandomizerOnPlayerUpdateHandler() { ) { GiveItemEntryWithoutActor(gPlayState, ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY)); } + + if ( + !GameInteractor::IsGameplayPaused() && + RAND_GET_OPTION(RSK_TRIFORCE_HUNT) + ) { + // Warp to credits + if (GameInteractor::State::TriforceHuntCreditsWarpActive) { + gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0xFFF2; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; + GameInteractor::State::TriforceHuntCreditsWarpActive = 0; + } + + // Reset Triforce Piece scale for GI animation. Triforce Hunt allows for multiple triforce models, + // and cycles through them based on the amount of triforce pieces collected. It takes a little while + // for the count to increase during the GI animation, so the model is entirely hidden until that piece + // has been added. That scale has to be reset after the textbox is closed, and this is the best way + // to ensure it's done at that point in time specifically. + if (GameInteractor::State::TriforceHuntPieceGiven) { + triforcePieceScale = 0.0f; + GameInteractor::State::TriforceHuntPieceGiven = 0; + } + } } void RandomizerRegisterHooks() { From cad6a626e9a191f310aceb3d441f0189719ee84b Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 01:00:39 +0200 Subject: [PATCH 14/48] Move randomizer sheik spawn to hook_handlers.cpp --- soh/soh/Enhancements/mods.cpp | 21 ---------------- .../Enhancements/randomizer/hook_handlers.cpp | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 0390b6e791c..694b42e59ab 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1161,26 +1161,6 @@ void RegisterAltTrapTypes() { }); } -void RegisterRandomizerSheikSpawn() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!gPlayState) return; - if (!IS_RANDO || !LINK_IS_ADULT || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHEIK_LA_HINT)) return; - switch (gPlayState->sceneNum) { - case SCENE_TEMPLE_OF_TIME: - if (gPlayState->roomCtx.curRoom.num == 1) { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0, SHEIK_TYPE_RANDO, false); - } - break; - case SCENE_INSIDE_GANONS_CASTLE: - if (gPlayState->roomCtx.curRoom.num == 1){ - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, 101, 150, 137, 0, 0, 0, SHEIK_TYPE_RANDO, false); - } - break; - default: break; - } - }); -} - void UpdateHurtContainerModeState(bool newState) { static bool hurtEnabled = false; if (hurtEnabled == newState) { @@ -1603,7 +1583,6 @@ void InitMods() { RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); - RegisterRandomizerSheikSpawn(); RegisterRandomizedEnemySizes(); RegisterOpenAllHours(); RegisterToTMedallions(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index a64ba0b6473..c5dbf3e3ab2 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -36,6 +36,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +#include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" #include "adult_trade_shuffle.h" #include "draw.h" @@ -1767,6 +1768,25 @@ void RandomizerOnPlayerUpdateHandler() { } } +void RandomizerOnSceneSpawnActorsHandler() { + if (LINK_IS_ADULT && RAND_GET_OPTION(RSK_SHEIK_LA_HINT)) { + switch (gPlayState->sceneNum) { + case SCENE_TEMPLE_OF_TIME: + if (gPlayState->roomCtx.curRoom.num == 1) { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0, SHEIK_TYPE_RANDO, false); + } + break; + case SCENE_INSIDE_GANONS_CASTLE: + if (gPlayState->roomCtx.curRoom.num == 1) { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, 101, 150, 137, 0, 0, 0, SHEIK_TYPE_RANDO, false); + } + break; + default: + break; + } + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -1779,6 +1799,7 @@ void RandomizerRegisterHooks() { static uint32_t onActorUpdateHook = 0; static uint32_t onPlayerUpdateHook = 0; static uint32_t onGameFrameUpdateHook = 0; + static uint32_t onSceneSpawnActorsHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { randomizerQueuedChecks = std::queue(); @@ -1796,6 +1817,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onActorUpdateHook); GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateHook); GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdateHook); + GameInteractor::Instance->UnregisterGameHook(onSceneSpawnActorsHook); onFlagSetHook = 0; onSceneFlagSetHook = 0; @@ -1808,6 +1830,7 @@ void RandomizerRegisterHooks() { onActorUpdateHook = 0; onPlayerUpdateHook = 0; onGameFrameUpdateHook = 0; + onSceneSpawnActorsHook = 0; if (!IS_RANDO) return; @@ -1822,5 +1845,6 @@ void RandomizerRegisterHooks() { onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); + onSceneSpawnActorsHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneSpawnActorsHandler); }); } From 0ed968db17096306af34456d1e5d604d1ab7e1ec Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:14:05 +0200 Subject: [PATCH 15/48] Update BossRush.h --- soh/soh/Enhancements/boss-rush/BossRush.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.h b/soh/soh/Enhancements/boss-rush/BossRush.h index 56337d40b92..0ae0f4924dd 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -10,8 +10,6 @@ void BossRush_SpawnBlueWarps(PlayState* play); void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ); void BossRush_HandleBlueWarpHeal(PlayState* play); void BossRush_InitSave(); -void BossRush_SetEquipment(uint8_t linkAge); -void BossRush_HandleCompleteBoss(PlayState* play); const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language); const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language); uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex); From 96961e7c49e12000b74dfcdac12bbb3cd974b0d1 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:56:26 +0200 Subject: [PATCH 16/48] Convert spoiling items to VB --- soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 6 ++++++ soh/src/code/z_sram.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 83416a62e72..0e4d23090c4 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -262,6 +262,8 @@ typedef enum { VB_SPAWN_HEART_CONTAINER, // Vanilla condition: true VB_BE_ABLE_TO_OPEN_DOORS, + // Vanilla condition: true + VB_REVERT_SPOILING_ITEMS, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index c5dbf3e3ab2..34e03469786 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1196,6 +1196,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case VB_REVERT_SPOILING_ITEMS: { + if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) { + *should = false; + } + break; + } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 9daa5a3cf7a..c5e8d90082e 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -198,7 +198,7 @@ void Sram_OpenSave() { } } - if (!(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) { + if (GameInteractor_Should(VB_REVERT_SPOILING_ITEMS, true, NULL)) { for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) { if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[i]) { INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i]; From 3e4080916e28b4818eaff2fdfd8a0de55fae760c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:57:20 +0200 Subject: [PATCH 17/48] Move load game stuff to hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 8 ++++++++ .../gamestates/ovl_file_choose/z_file_choose.c | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 34e03469786..907b7fc8d65 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1840,6 +1840,14 @@ void RandomizerRegisterHooks() { if (!IS_RANDO) return; + // Setup the modified entrance table and entrance shuffle table for rando + Entrance_Init(); + + // Handle randomized spawn positions after the save context has been setup from load + if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { + Entrance_SetSavewarpEntrance(); + } + onFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnFlagSetHandler); onSceneFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneFlagSetHandler); onPlayerUpdateForRCQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForRCQueueHandler); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index dcf3209cb7d..b8f8468d860 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -3045,16 +3045,6 @@ void FileChoose_LoadGame(GameState* thisx) { gSaveContext.naviTimer = 0; - if (IS_RANDO) { - // Setup the modified entrance table and entrance shuffle table for rando - Entrance_Init(); - - // Handle randomized spawn positions after the save context has been setup from load - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Entrance_SetSavewarpEntrance(); - } - } - GameInteractor_ExecuteOnLoadGame(gSaveContext.fileNum); } From aa4bfae5f3b8501002a56fd7d397111f5069a0ab Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:58:18 +0200 Subject: [PATCH 18/48] Move warp song handling to hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 5 +++++ soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 907b7fc8d65..ba6023643fd 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1662,6 +1662,11 @@ void RandomizerOnActorUpdateHandler(void* refActor) { } } } + + // In ER, override the warp song locations. Also removes the warp song cutscene + if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES) && actor->id == ACTOR_DEMO_KANKYO && actor->params == 0x000F) { // Warp Song particles + Entrance_SetWarpSongEntrance(); + } } //from z_player.c diff --git a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 89628cc3479..ed707ffad89 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -426,12 +426,6 @@ void DemoKankyo_KillDoorOfTimeCollision(DemoKankyo* this, PlayState* play) { void DemoKankyo_Update(Actor* thisx, PlayState* play) { DemoKankyo* this = (DemoKankyo*)thisx; this->actionFunc(this, play); - - // In ER, override the warp song locations. Also removes the warp song cutscene - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && - thisx->params == 0x000F) { // Warp Song particles - Entrance_SetWarpSongEntrance(); - } } void DemoKankyo_Draw(Actor* thisx, PlayState* play) { From dd60e6136c6381c7425a9e81e798ed19bf6f32f3 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:03:18 +0200 Subject: [PATCH 19/48] Convert being able to play bowling to VB --- .../game-interactor/GameInteractor.h | 2 ++ .../Enhancements/randomizer/hook_handlers.cpp | 6 +++++ .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 23 ++++--------------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 0e4d23090c4..03f437126d5 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -264,6 +264,8 @@ typedef enum { VB_BE_ABLE_TO_OPEN_DOORS, // Vanilla condition: true VB_REVERT_SPOILING_ITEMS, + // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP) || BREG(2) + VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, /*** Play Cutscenes ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ba6023643fd..7c3079eeb8b 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1202,6 +1202,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING: { + // Only check for bomb bag when bombchus aren't in logic + // and only check for bombchus when bombchus are in logic + *should = INV_CONTENT((RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) ? ITEM_BOMBCHU : ITEM_BOMB)) != ITEM_NONE; + break; + } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 6df2802f831..e3494d2981d 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -141,25 +141,10 @@ void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, PlayState* play) { if (frameCount == 30.0f) { this->dialogState = TEXT_STATE_EVENT; - // Check for beaten Dodongo's Cavern if Rando is disabled - if (!IS_RANDO) { - if ((Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) || BREG(2)) { - this->actor.textId = 0xBF; - } else { - this->actor.textId = 0x7058; - } - } - - // In randomizer, only check for bomb bag when bombchus aren't in logic - // and only check for bombchus when bombchus are in logic - if (IS_RANDO) { - u8 bombchusInLogic = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC); - if ((!bombchusInLogic && INV_CONTENT(ITEM_BOMB) == ITEM_NONE) || - (bombchusInLogic && INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE)) { - this->actor.textId = 0x7058; - } else { - this->actor.textId = 0xBF; - } + if (GameInteractor_Should(VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, (Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) || BREG(2), NULL)) { + this->actor.textId = 0xBF; + } else { + this->actor.textId = 0x7058; } } Message_ContinueTextbox(play, this->actor.textId); From 01edf35b665aadaf0f1a823eff1424e0d6021956 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:04:44 +0200 Subject: [PATCH 20/48] Move shooting gallery man handling to hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 13 +++++++++++++ .../actors/ovl_En_Syateki_Man/z_en_syateki_man.c | 9 --------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 7c3079eeb8b..3bd87eb5fa6 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1614,6 +1614,19 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } } + + if ( + // If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting gallery man + actor->id == ACTOR_EN_SYATEKI_MAN && + RAND_GET_OPTION(RSK_SHUFFLE_INTERIOR_ENTRANCES) && + ( + (LINK_IS_CHILD && Entrance_SceneAndSpawnAre(SCENE_SHOOTING_GALLERY, 0x00)) || //Kakariko Village -> Adult Shooting Gallery, index 003B in the entrance table + (LINK_IS_ADULT && Entrance_SceneAndSpawnAre(SCENE_SHOOTING_GALLERY, 0x01)) //Market -> Child Shooting Gallery, index 016D in the entrance table + ) + ) { + Actor_Kill(actor); + return; + } } void RandomizerOnGameFrameUpdateHandler() { diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index eca7cc18ce7..dcaaa897b1c 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -157,15 +157,6 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) { s32 pad; EnSyatekiMan* this = (EnSyatekiMan*)thisx; - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_INTERIOR_ENTRANCES)) { - // If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting gallery man - if ((LINK_IS_CHILD && Entrance_SceneAndSpawnAre(SCENE_SHOOTING_GALLERY, 0x00)) || //Kakariko Village -> Adult Shooting Gallery, index 003B in the entrance table - (LINK_IS_ADULT && Entrance_SceneAndSpawnAre(SCENE_SHOOTING_GALLERY, 0x01))) { //Market -> Child Shooting Gallery, index 016D in the entrance table - Actor_Kill(thisx); - return; - } - } - osSyncPrintf("\n\n"); // "Old man appeared!! Muhohohohohohohon" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 親父登場!!むほほほほほほほーん ☆☆☆☆☆ \n" VT_RST); From 88056b7a5a83a66625a8f440e23e385015dc9e3a Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:05:12 +0200 Subject: [PATCH 21/48] Move spirit temple silver block removal to hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 13 +++++++++++++ .../actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c | 9 --------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 3bd87eb5fa6..dad07a9fa77 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1615,6 +1615,19 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } + // In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway + // can be guaranteed accessible + if ( + actor->id == ACTOR_OBJ_OSHIHIKI && + LINK_IS_CHILD && + ResourceMgr_IsGameMasterQuest() && + play->sceneNum == SCENE_SPIRIT_TEMPLE && actor->room == 6 && // Spirit Temple silver block hallway + actor->params == 0x9C7 // Silver block that is marked as in the hole + ) { + Actor_Kill(actor); + return; + } + if ( // If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting gallery man actor->id == ACTOR_EN_SYATEKI_MAN && diff --git a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c index ae26db3ac99..026598ac923 100644 --- a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c +++ b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c @@ -273,15 +273,6 @@ void ObjOshihiki_Init(Actor* thisx, PlayState* play2) { PlayState* play = play2; ObjOshihiki* this = (ObjOshihiki*)thisx; - // In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway - // can be guaranteed accessible - if (IS_RANDO && LINK_IS_CHILD && ResourceMgr_IsGameMasterQuest() && - play->sceneNum == SCENE_SPIRIT_TEMPLE && thisx->room == 6 && // Spirit Temple silver block hallway - thisx->params == 0x9C7) { // Silver block that is marked as in the hole - Actor_Kill(thisx); - return; - } - ObjOshihiki_CheckType(this, play); if ((((this->dyna.actor.params >> 8) & 0xFF) >= 0) && (((this->dyna.actor.params >> 8) & 0xFF) <= 0x3F)) { From 1f4798048438f77340bc01c9992f3bfd350c121a Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:38:16 +0200 Subject: [PATCH 22/48] Fix build --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 75 +++++++++---------- .../Enhancements/randomizer/hook_handlers.cpp | 4 +- soh/src/code/z_sram.c | 1 + .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 1 + 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index b5ab7b2141f..2eda0381f28 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -174,6 +174,43 @@ void BossRush_SpawnBlueWarps(PlayState* play) { } } +void BossRush_SetEquipment(uint8_t linkAge) { + std::array brButtonItems; + std::array brCButtonSlots; + + // Set Child Equipment. + if (linkAge == LINK_AGE_CHILD) { + brButtonItems = { + ITEM_SWORD_KOKIRI, ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE + }; + + brCButtonSlots = { SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); + // Set Adult equipment. + } else { + brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }; + + brCButtonSlots = { SLOT_BOW, SLOT_HAMMER, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); + } + + // Button Items + for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.buttonItems); button++) { + gSaveContext.equips.buttonItems[button] = brButtonItems[button]; + } + + // C buttons + for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.cButtonSlots); button++) { + gSaveContext.equips.cButtonSlots[button] = brCButtonSlots[button]; + } +} + void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // If warping from Chamber of Sages, choose the correct boss room to teleport to. @@ -456,44 +493,6 @@ void BossRush_InitSave() { } } -void BossRush_SetEquipment(uint8_t linkAge) { - - std::array brButtonItems; - std::array brCButtonSlots; - - // Set Child Equipment. - if (linkAge == LINK_AGE_CHILD) { - brButtonItems = { - ITEM_SWORD_KOKIRI, ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE - }; - - brCButtonSlots = { SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; - - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); - // Set Adult equipment. - } else { - brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, - ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }; - - brCButtonSlots = { SLOT_BOW, SLOT_HAMMER, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; - - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); - } - - // Button Items - for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.buttonItems); button++) { - gSaveContext.equips.buttonItems[button] = brButtonItems[button]; - } - - // C buttons - for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.cButtonSlots); button++) { - gSaveContext.equips.cButtonSlots[button] = brCButtonSlots[button]; - } -} - void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { // Disable doors so the player can't leave the boss rooms backwards. diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index dad07a9fa77..4bd1842f6eb 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1620,8 +1620,8 @@ void RandomizerOnActorInitHandler(void* actorRef) { if ( actor->id == ACTOR_OBJ_OSHIHIKI && LINK_IS_CHILD && - ResourceMgr_IsGameMasterQuest() && - play->sceneNum == SCENE_SPIRIT_TEMPLE && actor->room == 6 && // Spirit Temple silver block hallway + IsGameMasterQuest() && + gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE && actor->room == 6 && // Spirit Temple silver block hallway actor->params == 0x9C7 // Silver block that is marked as in the hole ) { Actor_Kill(actor); diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index c5e8d90082e..d236b2a92e9 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -2,6 +2,7 @@ #include "vt.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/savefile.h" diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index e3494d2981d..4701bcb5032 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -3,6 +3,7 @@ #include "overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" #include "objects/object_bg/object_bg.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) From 35a7327b1de20d8c4e166858718e6494cb846dc9 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:40:20 +0200 Subject: [PATCH 23/48] Move last beehive stuff to hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 5 +++++ soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c | 7 +------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 4bd1842f6eb..91a7397c3c2 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1699,6 +1699,11 @@ void RandomizerOnActorUpdateHandler(void* refActor) { if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES) && actor->id == ACTOR_DEMO_KANKYO && actor->params == 0x000F) { // Warp Song particles Entrance_SetWarpSongEntrance(); } + + if (actor->id == ACTOR_OBJ_COMB) { + ObjComb* combActor = reinterpret_cast(actor); + combActor->actor.shape.rot.x = Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x; + } } //from z_player.c diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c index 19bf701fa73..a804da12ebd 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c @@ -200,12 +200,7 @@ void ObjComb_Update(Actor* thisx, PlayState* play) { this->unk_1B2 += 0x2EE0; this->actionFunc(this, play); - s16 wiggleOffset = this->unk_1B0; - - if (IS_RANDO && this->unk_1B0 < 0) { - wiggleOffset = 0; - } - this->actor.shape.rot.x = Math_SinS(this->unk_1B2) * wiggleOffset + this->actor.home.rot.x; + this->actor.shape.rot.x = Math_SinS(this->unk_1B2) * this->unk_1B0 + this->actor.home.rot.x; } void ObjComb_Draw(Actor* thisx, PlayState* play) { From 96337e8b44a7d8ff21a756102ffd1f9679681ef9 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:53:29 +0200 Subject: [PATCH 24/48] Fix build --- soh/src/code/code_800EC960.c | 1 + soh/src/code/z_horse.c | 1 + soh/src/code/z_sram.c | 1 + soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c | 1 + soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 1 + soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c | 1 + soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 1 + soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c | 1 + soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 1 + soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 1 + soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 1 + soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c | 1 + soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 1 + soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c | 1 + soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c | 1 + 15 files changed, 15 insertions(+) diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c index 055c6360729..145ab7c1ca6 100644 --- a/soh/src/code/code_800EC960.c +++ b/soh/src/code/code_800EC960.c @@ -2,6 +2,7 @@ #include "global.h" #include "soh/Enhancements/audio/AudioEditor.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" // TODO: can these macros be shared between files? code_800F9280 seems to use // versions without any casts... diff --git a/soh/src/code/z_horse.c b/soh/src/code/z_horse.c index d72b80396a8..33ba7a84d7f 100644 --- a/soh/src/code/z_horse.c +++ b/soh/src/code/z_horse.c @@ -2,6 +2,7 @@ #include "vt.h" #include #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" s32 func_8006CFC0(s32 scene) { s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS, SCENE_LON_LON_RANCH }; diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index d236b2a92e9..8a848f30138 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -3,6 +3,7 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/savefile.h" diff --git a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c index f24174fbc7c..032a487a667 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c @@ -15,6 +15,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index 6a996ebd05d..f72b6a11afe 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -10,6 +10,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index f1ef4975f53..d4b641b9603 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -12,6 +12,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/boss-rush/BossRushTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index a63deb7d388..97cc537b4c7 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -7,6 +7,7 @@ #include "objects/object_ganon_anime3/object_ganon_anime3.h" #include "objects/object_geff/object_geff.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 32c5aef5398..6fee2ebc951 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -5,6 +5,7 @@ #include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index c4e664e90ee..f5b8ff01f5a 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -13,6 +13,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 7b61e408895..71c804e5221 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -12,6 +12,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 089b703ad96..36d9fb93482 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -5,6 +5,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 6b65c73a367..fecb03186ec 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -16,6 +16,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 4701bcb5032..26e7f7e7a17 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -4,6 +4,7 @@ #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" #include "objects/object_bg/object_bg.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) diff --git a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c index 8b0bf8dea99..08d1e1c9818 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_ka/object_ka.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA | ACTOR_FLAG_NO_LOCKON) diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c index b77130ca35a..9c4224181de 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c @@ -3,6 +3,7 @@ #include "textures/icon_item_static/icon_item_static.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" extern const char* digitTextures[]; From cc4e7535161e781f2b0ec8af2f8db15112213f7c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:46:15 +0200 Subject: [PATCH 25/48] Add VB_CLOSE_PAUSE_MENU --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 7 +++++++ soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ .../overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c | 4 +--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 2eda0381f28..6c79182c99d 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -495,6 +495,13 @@ void BossRush_InitSave() { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + // Skip past the "Save?" window when pressing B while paused and instead close the menu. + case VB_CLOSE_PAUSE_MENU: { + if (CHECK_BTN_ALL(gPlayState->state.input[0].press.button, BTN_B)) { + *should = true; + } + break; + } // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: case VB_SPAWN_HEART_CONTAINER: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 03f437126d5..298d649e6b1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -266,6 +266,8 @@ typedef enum { VB_REVERT_SPOILING_ITEMS, // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP) || BREG(2) VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, + // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) + VB_CLOSE_PAUSE_MENU, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 424c823d603..5156d945b78 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -3991,9 +3991,7 @@ void KaleidoScope_Update(PlayState* play) case 6: switch (pauseCtx->unk_1E4) { case 0: - // Boss Rush skips past the "Save?" window when pressing B while paused. - if (CHECK_BTN_ALL(input->press.button, BTN_START) || - (CHECK_BTN_ALL(input->press.button, BTN_B) && IS_BOSS_RUSH)) { + if (GameInteractor_Should(VB_CLOSE_PAUSE_MENU, CHECK_BTN_ALL(input->press.button, BTN_START), NULL)) { if (CVarGetInteger(CVAR_CHEAT("EasyPauseBuffer"), 0) || CVarGetInteger(CVAR_CHEAT("EasyInputBuffer"), 0)) { // Easy pause buffer is 13 frames, 12 for kaledio to end, and one more to advance a single frame CVarSetInteger(CVAR_GENERAL("CheatEasyPauseBufferTimer"), 13); From 31035203492bb88fb76a9ebe1cdc0288b75311cb Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:46:44 +0200 Subject: [PATCH 26/48] Add VB_BE_ABLE_TO_SAVE --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 1 + soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ .../overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c | 6 +++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 6c79182c99d..bb638520eb1 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -502,6 +502,7 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: case VB_SPAWN_HEART_CONTAINER: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 298d649e6b1..41527577fe4 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -266,6 +266,8 @@ typedef enum { VB_REVERT_SPOILING_ITEMS, // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP) || BREG(2) VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, + // Vanilla condition: true + VB_BE_ABLE_TO_SAVE, // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) VB_CLOSE_PAUSE_MENU, diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 5156d945b78..30d3f0b9e04 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -4375,7 +4375,7 @@ void KaleidoScope_Update(PlayState* play) VREG(88) = 66; WREG(2) = 0; pauseCtx->alpha = 255; - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true, NULL)) { pauseCtx->state = 0xE; } else { pauseCtx->state = 0xF; @@ -4423,7 +4423,7 @@ void KaleidoScope_Update(PlayState* play) case 0x10: if (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_START)) { - if (pauseCtx->promptChoice == 0 && !IS_BOSS_RUSH) { + if (pauseCtx->promptChoice == 0 && GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true, NULL)) { Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); Play_SaveSceneFlags(play); @@ -4496,7 +4496,7 @@ void KaleidoScope_Update(PlayState* play) R_PAUSE_MENU_MODE = 0; func_800981B8(&play->objectCtx); func_800418D0(&play->colCtx, play); - if (pauseCtx->promptChoice == 0 && !IS_BOSS_RUSH) { + if (pauseCtx->promptChoice == 0 && GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true, NULL)) { Play_TriggerRespawn(play); gSaveContext.respawnFlag = -2; // In ER, handle death warp to last entrance from grottos From 8ebc17660f21dd2291f03a0a35e1425fd6a42fc9 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:47:19 +0200 Subject: [PATCH 27/48] Add VB_RENDER_YES_ON_CONTINUE_PROMPT --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 18 ++++++++++++++++++ .../game-interactor/GameInteractor.h | 2 ++ .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 6 +----- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index bb638520eb1..4ebd189feee 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -12,6 +12,11 @@ extern "C" { #include "macros.h" #include "variables.h" extern PlayState* gPlayState; + + Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); + #include "textures/icon_item_nes_static/icon_item_nes_static.h" + #include "textures/icon_item_ger_static/icon_item_ger_static.h" + #include "textures/icon_item_fra_static/icon_item_fra_static.h" } typedef struct BossRushSetting { @@ -493,6 +498,12 @@ void BossRush_InitSave() { } } +static void* sSavePromptNoChoiceTexs[] = { + (void*)gPauseNoENGTex, + (void*)gPauseNoGERTex, + (void*)gPauseNoFRATex +}; + void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { // Skip past the "Save?" window when pressing B while paused and instead close the menu. @@ -502,6 +513,13 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + // Show "No" twice because the player can't continue. + case VB_RENDER_YES_ON_CONTINUE_PROMPT: { + Gfx** disp = static_cast(optionalArg); + *disp = KaleidoScope_QuadTextureIA8(*disp, sSavePromptNoChoiceTexs[gSaveContext.language], 48, 16, 12); + *should = false; + break; + } case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 41527577fe4..096f41a8366 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -268,6 +268,8 @@ typedef enum { VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, // Vanilla condition: true VB_BE_ABLE_TO_SAVE, + // Vanilla condition: true + VB_RENDER_YES_ON_CONTINUE_PROMPT, // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) VB_CLOSE_PAUSE_MENU, diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 30d3f0b9e04..44709141788 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -1640,13 +1640,9 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) { gDPSetCombineMode(POLY_KAL_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_RENDER_YES_ON_CONTINUE_PROMPT, true, &POLY_KAL_DISP)) { POLY_KAL_DISP = KaleidoScope_QuadTextureIA8( POLY_KAL_DISP, sPromptChoiceTexs[gSaveContext.language][0], 48, 16, 12); - } else { - // Show "No" twice in Boss Rush because the player can't save within it. - POLY_KAL_DISP = KaleidoScope_QuadTextureIA8( - POLY_KAL_DISP, sPromptChoiceTexs[gSaveContext.language][1], 48, 16, 12); } POLY_KAL_DISP = From 56e55547d0532fc09cf8af63d0e7b0a123356eb0 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 22:15:35 +0200 Subject: [PATCH 28/48] Add VB_SPAWN_BLUE_WARP --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 68 +++++++++++++++++++ .../game-interactor/GameInteractor.h | 2 + .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 4 +- .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 6 +- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 12 ++-- .../actors/ovl_Boss_Goma/z_boss_goma.c | 11 ++- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 11 ++- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 12 ++-- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 16 +++-- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 14 ++-- 10 files changed, 115 insertions(+), 41 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 4ebd189feee..90f49ddc22e 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -11,6 +11,9 @@ extern "C" { #include "functions.h" #include "macros.h" #include "variables.h" + #include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h" + #include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h" + #include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h" extern PlayState* gPlayState; Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); @@ -506,6 +509,71 @@ static void* sSavePromptNoChoiceTexs[] = { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + case VB_SPAWN_BLUE_WARP: { + switch (gPlayState->sceneNum) { + case SCENE_DEKU_TREE_BOSS: { + BossGoma* bossGoma = static_cast(optionalArg); + static Vec3f roomCenter = { -150.0f, 0.0f, -350.0f }; + Vec3f childPos = roomCenter; + + for (s32 i = 0; i < 10000; i++) { + if ((fabsf(childPos.x - GET_PLAYER(gPlayState)->actor.world.pos.x) < 100.0f && + fabsf(childPos.z - GET_PLAYER(gPlayState)->actor.world.pos.z) < 100.0f) || + (fabsf(childPos.x - bossGoma->actor.world.pos.x) < 150.0f && + fabsf(childPos.z - bossGoma->actor.world.pos.z) < 150.0f)) { + childPos.x = Rand_CenteredFloat(400.0f) + -150.0f; + childPos.z = Rand_CenteredFloat(400.0f) + -350.0f; + } else { + break; + } + } + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, childPos.x, bossGoma->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + } + case SCENE_DODONGOS_CAVERN_BOSS: + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + case SCENE_JABU_JABU_BOSS: { + static Vec3f sWarpPos[] = { + { 10.0f, 0.0f, 30.0f }, + { 260.0f, 0.0f, -470.0f }, + { -240.0f, 0.0f, -470.0f }, + }; + + s32 sp7C = 2; + for (s32 i = 2; i > 0; i -= 1) { + if (Math_Vec3f_DistXYZ(&sWarpPos[i], &GET_PLAYER(gPlayState)->actor.world.pos) < + Math_Vec3f_DistXYZ(&sWarpPos[i - 1], &GET_PLAYER(gPlayState)->actor.world.pos)) { + sp7C = i - 1; + } + } + + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + } + case SCENE_FOREST_TEMPLE_BOSS: + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 14.0f, -33.0f, -3315.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + case SCENE_FIRE_TEMPLE_BOSS: + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + case SCENE_WATER_TEMPLE_BOSS: { + BossMo* bossMo = static_cast(optionalArg); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, bossMo->actor.world.pos.x, -280.0f, bossMo->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + case SCENE_SPIRIT_TEMPLE_BOSS: + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + case SCENE_SHADOW_TEMPLE_BOSS: + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -50.0f, 0.0f, 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + default: + break; + } + *should = false; + break; + } // Skip past the "Save?" window when pressing B while paused and instead close the menu. case VB_CLOSE_PAUSE_MENU: { if (CHECK_BTN_ALL(gPlayState->state.input[0].press.button, BTN_B)) { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 096f41a8366..8fd1c885b87 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -272,6 +272,8 @@ typedef enum { VB_RENDER_YES_ON_CONTINUE_PROMPT, // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) VB_CLOSE_PAUSE_MENU, + // Vanilla condition: true + VB_SPAWN_BLUE_WARP, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index 599eb7a0937..a8036ba07ad 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -1851,10 +1851,8 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_ADULT, false); } this->skelAnime.playSpeed = 0.0f; Flags_SetClear(play, play->roomCtx.curRoom.num); diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index f72b6a11afe..5464b962417 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -783,18 +783,16 @@ void BossFd2_Death(BossFd2* this, PlayState* play) { if (bossFd->work[BFD_ACTION_STATE] == BOSSFD_SKULL_BURN) { this->deathState = DEATH_FINISH; mainCam->eye = this->camData.eye; + mainCam->eye = this->camData.eye; mainCam->eyeNext = this->camData.eye; mainCam->at = this->camData.at; func_800C08AC(play, this->deathCamera, 0); this->deathCamera = 0; func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, - WARP_DUNGEON_ADULT, true); } Flags_SetClear(play, play->roomCtx.curRoom.num); } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 4dd352eb711..1a1b0c24bf5 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -233,8 +233,10 @@ void BossGanondrof_Init(Actor* thisx, PlayState* play) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { Actor_Kill(&this->actor); - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, - GND_BOSSROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, + GND_BOSSROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 200.0f + GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, GND_BOSSROOM_CENTER_Z, 0, 0, 0, 0, true); @@ -1060,8 +1062,10 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) { bodyDecayLevel = 10; if (this->timers[0] == 150) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR); - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, - GND_BOSSROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y, + GND_BOSSROOM_CENTER_Z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + } } Math_ApproachZeroF(&this->cameraEye.y, 0.05f, 1.0f); // GND_BOSSROOM_CENTER_Y + 33.0f diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 6fee2ebc951..ad8b8b9103c 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -340,8 +340,10 @@ void BossGoma_Init(Actor* thisx, PlayState* play) { if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { Actor_Kill(&this->actor); - Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -640.0f, 0.0f, 0, 0, - 0, WARP_DUNGEON_CHILD); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -640.0f, 0.0f, 0, 0, + 0, WARP_DUNGEON_CHILD); + } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 141.0f, -640.0f, -84.0f, 0, 0, 0, 0, true); } @@ -1155,12 +1157,9 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) { } } - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, childPos.x, this->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_CHILD); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, childPos.x, this->actor.world.pos.y, - childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); } Flags_SetClear(play, play->roomCtx.curRoom.num); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index f5b8ff01f5a..6551f25b0d1 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -371,8 +371,10 @@ void BossMo_Init(Actor* thisx, PlayState* play2) { Collider_SetCylinder(play, &this->coreCollider, &this->actor, &sCylinderInit); if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { Actor_Kill(&this->actor); - Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -280.0f, 0.0f, 0, - 0, 0, WARP_DUNGEON_ADULT); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, -280.0f, 0.0f, 0, + 0, 0, WARP_DUNGEON_ADULT); + } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -200.0f, -280.0f, 0.0f, 0, 0, 0, 0, true); } @@ -1119,13 +1121,10 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { BossMo_SpawnDroplet(MO_FX_DROPLET, (BossMoEffect*)play->specialEffects, &spD4, &spE0, ((300 - indS1) * .0015f) + 0.13f); } - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, this->actor.world.pos.x, -280.0f, this->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, this->actor.world.pos.x, -280.0f, - this->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 71c804e5221..6a4b0f30c37 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -294,8 +294,10 @@ void BossSst_Init(Actor* thisx, PlayState* play2) { this->actor.home.pos = this->actor.world.pos; this->actor.shape.rot.y = 0; if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, - ROOM_CENTER_Z + 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, + ROOM_CENTER_Z + 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, ROOM_CENTER_X, ROOM_CENTER_Y, ROOM_CENTER_Z - 200.0f, 0, 0, 0, 0, true); @@ -1205,8 +1207,10 @@ void BossSst_HeadFinish(BossSst* this, PlayState* play) { Flags_SetClear(play, play->roomCtx.curRoom.num); } } else if (this->effects[0].alpha == 0) { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, ROOM_CENTER_Z, 0, 0, 0, - WARP_DUNGEON_ADULT, true); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, ROOM_CENTER_X, ROOM_CENTER_Y, ROOM_CENTER_Z, 0, 0, 0, + WARP_DUNGEON_ADULT, true); + } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, (Math_SinS(this->actor.shape.rot.y) * 200.0f) + ROOM_CENTER_X, ROOM_CENTER_Y, diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 36d9fb93482..4c198d07fd8 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -536,9 +536,14 @@ void BossTw_Init(Actor* thisx, PlayState* play2) { if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { // twinrova has been defeated. Actor_Kill(&this->actor); - Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, - 0, 0, WARP_DUNGEON_ADULT); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -600.0f, 230.0f, 0.0f, 0, 0, 0, 0, true); + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, + 0, 0, WARP_DUNGEON_ADULT); + } + + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -600.0f, 230.0f, 0.0f, 0, 0, 0, 0, true); + } } else { sKotakePtr = (BossTw*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_BOSS_TW, this->actor.world.pos.x, this->actor.world.pos.y, @@ -2796,12 +2801,9 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { func_80064534(play, &play->csCtx); Player_SetCsActionWithHaltedActors(play, &this->actor, 7); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR); - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, - WARP_DUNGEON_ADULT, true); } if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index fecb03186ec..16cb91d99d9 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -642,9 +642,12 @@ void BossVa_Init(Actor* thisx, PlayState* play2) { if (Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { warpId = ACTOR_DOOR_WARP1; } - Actor_Spawn(&play->actorCtx, play, warpId, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 0, 0, 0, - 0, true); //! params could be WARP_DUNGEON_CHILD however this can also spawn Ru1 + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { + Actor_Spawn(&play->actorCtx, play, warpId, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, + 0, true); //! params could be WARP_DUNGEON_CHILD however this can also spawn Ru1 + } + if (GameInteractor_Should(VB_SPAWN_HEART_CONTAINER, true, NULL)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.world.pos.x + 160.0f, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); @@ -1671,12 +1674,9 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) { } } - if (!IS_BOSS_RUSH) { + if (GameInteractor_Should(VB_SPAWN_BLUE_WARP, true, this)) { Actor_Spawn(&play->actorCtx, play, ACTOR_EN_RU1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, sWarpPos[sp7C].z, 0, 0, 0, 0, true); - } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, - sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); } } case DEATH_FINISH: From e3a779eebf06ec73cc711cf67d103ab327bdce92 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 22:46:09 +0200 Subject: [PATCH 29/48] Add VB_BLUE_WARP_ADULT_WARP_OUT --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 11 ++++++++++- soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c | 6 ++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 90f49ddc22e..7e4a1e0f99b 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -220,7 +220,6 @@ void BossRush_SetEquipment(uint8_t linkAge) { } void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { - // If warping from Chamber of Sages, choose the correct boss room to teleport to. if (play->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { // Gohma & Phantom Ganon @@ -274,6 +273,10 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { } } } + + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; } void BossRush_HandleBlueWarpHeal(PlayState* play) { @@ -509,6 +512,12 @@ static void* sSavePromptNoChoiceTexs[] = { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + case VB_BLUE_WARP_ADULT_WARP_OUT: { + DoorWarp1* blueWarp = static_cast(optionalArg); + BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); + *should = false; + break; + } case VB_SPAWN_BLUE_WARP: { switch (gPlayState->sceneNum) { case SCENE_DEKU_TREE_BOSS: { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 8fd1c885b87..651c1b42dee 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -274,6 +274,8 @@ typedef enum { VB_CLOSE_PAUSE_MENU, // Vanilla condition: true VB_SPAWN_BLUE_WARP, + // Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF + VB_BLUE_WARP_ADULT_WARP_OUT, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index ff55bf65fa9..e2ce32bf4bc 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -758,10 +758,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { } this->warpTimer++; - if (this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF) { - if (IS_BOSS_RUSH) { - BossRush_HandleBlueWarp(play, this->actor.world.pos.x, this->actor.world.pos.z); - } else if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { + if (GameInteractor_Should(VB_BLUE_WARP_ADULT_WARP_OUT, this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF, this)) { + if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) { From a3b985d3c81e5331a3dadc685f7c427eae5b7fde Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 23:37:07 +0200 Subject: [PATCH 30/48] Add VB_BG_BREAKWALL_BREAK --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 6 ++++++ soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 7e4a1e0f99b..0a04930cdbf 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -597,6 +597,12 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } + + // Break the dodongo breakable floor immediately so the player can jump in the hole immediately. + case VB_BG_BREAKWALL_BREAK: + *should = true; + break; + case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 651c1b42dee..1a37feb3d5e 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -276,6 +276,8 @@ typedef enum { VB_SPAWN_BLUE_WARP, // Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF VB_BLUE_WARP_ADULT_WARP_OUT, + // Vanilla condition: this->collider.base.acFlags & 2 + VB_BG_BREAKWALL_BREAK, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 03c9e96ad57..c2db563b9cb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -8,6 +8,7 @@ #include "scenes/dungeons/ddan/ddan_scene.h" #include "objects/object_bwall/object_bwall.h" #include "objects/object_kingdodongo/object_kingdodongo.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -274,9 +275,8 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { } } } - - // Break the floor immediately in Boss Rush so the player can jump in the hole immediately. - if (this->collider.base.acFlags & 2 || blueFireArrowHit || IS_BOSS_RUSH) { + + if (GameInteractor_Should(VB_BG_BREAKWALL_BREAK, this->collider.base.acFlags & 2 || blueFireArrowHit, NULL)) { Vec3f effectPos; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; From 25cb867eef225c51887b9364eda2ddf83109eeb1 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 23:37:52 +0200 Subject: [PATCH 31/48] Convert Saria stuff to VB --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 7 +++++++ .../overlays/actors/ovl_Demo_Sa/z_demo_sa.c | 21 ++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 0a04930cdbf..77f0729a401 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -616,6 +616,13 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* void BossRush_OnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); + if (actor->id == ACTOR_DEMO_SA && gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { + BossRush_SpawnBlueWarps(gPlayState); + Actor_Kill(actor); + GET_PLAYER(gPlayState)->actor.world.rot.y = GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306; + return; + } + // Remove chests, mainly for the chest in King Dodongo's boss room. // Remove bushes, used in Gohma's arena. // Remove pots, used in Barinade's and Ganondorf's arenas. diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c index b0d210bbc6e..26bf4c761ba 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c @@ -8,7 +8,6 @@ #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_sa/object_sa.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -257,21 +256,13 @@ void func_8098E960(DemoSa* this, PlayState* play) { if ((gSaveContext.chamberCutsceneNum == 0) && (gSaveContext.sceneSetupIndex < 4)) { player = GET_PLAYER(play); - if (!IS_BOSS_RUSH) { - this->action = 1; - play->csCtx.segment = D_8099010C; - gSaveContext.cutsceneTrigger = 2; - if (GameInteractor_Should(VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { - Item_Give(play, ITEM_MEDALLION_FOREST); - } - player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; - } else { - this->action = 1; - if (gSaveContext.linkAge == LINK_AGE_CHILD) { - player->actor.world.rot.y = player->actor.shape.rot.y = -5461 + 0x8000; - } - BossRush_SpawnBlueWarps(play); + this->action = 1; + play->csCtx.segment = D_8099010C; + gSaveContext.cutsceneTrigger = 2; + if (GameInteractor_Should(VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FOREST); } + player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000; } } From b635a2688059491801d8bf47de79a0f44d1b4be7 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 23:38:07 +0200 Subject: [PATCH 32/48] Remove now unused check --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 77f0729a401..681b454966d 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -289,10 +289,6 @@ void BossRush_HandleBlueWarpHeal(PlayState* play) { } void BossRush_HandleCompleteBoss(PlayState* play) { - if (!IS_BOSS_RUSH) { - return; - } - gSaveContext.isBossRushPaused = 1; switch (play->sceneNum) { case SCENE_DEKU_TREE_BOSS: From 4b6ef88cee2a6e8d888fb3d7c6c63d101453f158 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 31 Jul 2024 23:57:42 +0200 Subject: [PATCH 33/48] Add VB_GANON_HEAL_BEFORE_FIGHT --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 6 ++++++ soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 681b454966d..ad634abcc9e 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -508,6 +508,12 @@ static void* sSavePromptNoChoiceTexs[] = { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + case VB_GANON_HEAL_BEFORE_FIGHT: { + if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER) { + *should = false; + } + break; + } case VB_BLUE_WARP_ADULT_WARP_OUT: { DoorWarp1* blueWarp = static_cast(optionalArg); BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 1a37feb3d5e..525dfbc1e6f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -278,6 +278,8 @@ typedef enum { VB_BLUE_WARP_ADULT_WARP_OUT, // Vanilla condition: this->collider.base.acFlags & 2 VB_BG_BREAKWALL_BREAK, + // Vanilla condition: true + VB_GANON_HEAL_BEFORE_FIGHT, /*** Play Cutscenes ***/ diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index d4b641b9603..1c494fb78b2 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -582,7 +582,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { BossGanon_SetIntroCsCamera(this, 11); this->unk_198 = 2; this->timers[2] = 110; - if (!(IS_BOSS_RUSH && gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER)) { + if (GameInteractor_Should(VB_GANON_HEAL_BEFORE_FIGHT, true, NULL)) { gSaveContext.healthAccumulator = 0x140; } Audio_QueueSeqCmd(NA_BGM_STOP); From 1fcc73d6bae0a30a2e7b960249f194b187afb9cf Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 18 Aug 2024 20:09:58 +0200 Subject: [PATCH 34/48] Update hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9f1dcbad58c..d52bde1a256 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -36,6 +36,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" #include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" #include "adult_trade_shuffle.h" #include "draw.h" @@ -1683,6 +1684,8 @@ void RandomizerOnGameFrameUpdateHandler() { } } +extern "C" void func_8099485C(DoorGerudo* gerudoDoor, PlayState* play); + void RandomizerOnActorUpdateHandler(void* refActor) { Actor* actor = static_cast(refActor); @@ -1695,6 +1698,10 @@ void RandomizerOnActorUpdateHandler(void* refActor) { if (shutterDoor->doorType == SHUTTER_KEY_LOCKED) { shutterDoor->unk_16E = 0; } + } else if (actor->id == ACTOR_DOOR_GERUDO) { + DoorGerudo* gerudoDoor = (DoorGerudo*)actor; + gerudoDoor->actionFunc = func_8099485C; + gerudoDoor->dyna.actor.world.pos.y = gerudoDoor->dyna.actor.home.pos.y + 200.0f; } } From 2d5182556e4731e748e56c0f6ee2dc08d5691386 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sat, 24 Aug 2024 17:50:50 +0200 Subject: [PATCH 35/48] Fix blue warp offsets --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 2 +- .../Enhancements/game-interactor/GameInteractor.h | 2 +- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 9 +++++++++ .../overlays/actors/ovl_Door_Warp1/z_door_warp1.c | 14 +++++--------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index ad634abcc9e..d5086b47ad8 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -514,7 +514,7 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } - case VB_BLUE_WARP_ADULT_WARP_OUT: { + case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { DoorWarp1* blueWarp = static_cast(optionalArg); BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); *should = false; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 557ceef2da7..d3887d02786 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -275,7 +275,7 @@ typedef enum { // Vanilla condition: true VB_SPAWN_BLUE_WARP, // Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF - VB_BLUE_WARP_ADULT_WARP_OUT, + VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, // Vanilla condition: this->collider.base.acFlags & 2 VB_BG_BREAKWALL_BREAK, // Vanilla condition: true diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d52bde1a256..9465b7e0839 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1212,6 +1212,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = INV_CONTENT((RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) ? ITEM_BOMBCHU : ITEM_BOMB)) != ITEM_NONE; break; } + case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { + if ( + RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || + RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF + ) { + Entrance_OverrideBlueWarp(); + } + break; + } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index d6146d8d942..081ff5daa90 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -758,7 +758,7 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { } this->warpTimer++; - if (GameInteractor_Should(VB_BLUE_WARP_ADULT_WARP_OUT, this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF, this)) { + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF, this)) { if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); @@ -844,16 +844,12 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } + } - if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || - Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { - Entrance_OverrideBlueWarp(); - } + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; - } if (this->warpTimer >= 141) { f32 screenFillAlpha; From 4044918b558dff6b2fb6aca5d121366ca77bd449 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:03:59 +0200 Subject: [PATCH 36/48] Fixes from review --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 7 +++++++ soh/soh/Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 2 +- .../overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c | 4 +--- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index d5086b47ad8..0cda22ab82d 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -605,6 +605,13 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = true; break; + // Skip past the "Save?" window when dying and go to the "Continue?" screen immediately. + case VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH: { + PauseContext* pauseCtx = static_cast(optionalArg); + pauseCtx->state = 0xF; + *should = false; + break; + } case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index d3887d02786..2e90a77d089 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -269,6 +269,8 @@ typedef enum { // Vanilla condition: true VB_BE_ABLE_TO_SAVE, // Vanilla condition: true + VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH, + // Vanilla condition: true VB_RENDER_YES_ON_CONTINUE_PROMPT, // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) VB_CLOSE_PAUSE_MENU, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9465b7e0839..efa7520846f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1918,7 +1918,7 @@ void RandomizerRegisterHooks() { onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); - onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); + onPlayerUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); onSceneSpawnActorsHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneSpawnActorsHandler); }); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index c6ca2f72689..8434e41fb16 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -4371,10 +4371,8 @@ void KaleidoScope_Update(PlayState* play) VREG(88) = 66; WREG(2) = 0; pauseCtx->alpha = 255; - if (GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true, NULL)) { + if (GameInteractor_Should(VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH, true, pauseCtx)) { pauseCtx->state = 0xE; - } else { - pauseCtx->state = 0xF; } gSaveContext.deaths++; if (gSaveContext.deaths > 999) { From 90d4cafb95d1b15a6b04b7ff4e43367c05993628 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:04:29 +0200 Subject: [PATCH 37/48] Improve documentation --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 35 ++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 0cda22ab82d..f77ab7b38cf 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -508,18 +508,21 @@ static void* sSavePromptNoChoiceTexs[] = { void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + // Allow not healing before ganon case VB_GANON_HEAL_BEFORE_FIGHT: { if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER) { *should = false; } break; } + // Replace the blue warp transitions with ones that lead back to the chamber of sages case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { DoorWarp1* blueWarp = static_cast(optionalArg); BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); *should = false; break; } + // Spawn clean blue warps (no ruto, adult animation, etc) case VB_SPAWN_BLUE_WARP: { switch (gPlayState->sceneNum) { case SCENE_DEKU_TREE_BOSS: { @@ -541,9 +544,10 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, childPos.x, bossGoma->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); break; } - case SCENE_DODONGOS_CAVERN_BOSS: + case SCENE_DODONGOS_CAVERN_BOSS: { Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_ADULT, false); break; + } case SCENE_JABU_JABU_BOSS: { static Vec3f sWarpPos[] = { { 10.0f, 0.0f, 30.0f }, @@ -562,25 +566,31 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); break; } - case SCENE_FOREST_TEMPLE_BOSS: + case SCENE_FOREST_TEMPLE_BOSS: { Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 14.0f, -33.0f, -3315.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; - case SCENE_FIRE_TEMPLE_BOSS: + } + case SCENE_FIRE_TEMPLE_BOSS: { Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; + } case SCENE_WATER_TEMPLE_BOSS: { BossMo* bossMo = static_cast(optionalArg); Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, bossMo->actor.world.pos.x, -280.0f, bossMo->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; } - case SCENE_SPIRIT_TEMPLE_BOSS: + case SCENE_SPIRIT_TEMPLE_BOSS: { Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; - case SCENE_SHADOW_TEMPLE_BOSS: + } + case SCENE_SHADOW_TEMPLE_BOSS: { Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -50.0f, 0.0f, 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; - default: - break; + } + default: { + SPDLOG_WARNING("[BossRush]: Blue warp spawned in unhandled scene, ignoring"); + return; + } } *should = false; break; @@ -599,12 +609,11 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } - // Break the dodongo breakable floor immediately so the player can jump in the hole immediately. - case VB_BG_BREAKWALL_BREAK: + case VB_BG_BREAKWALL_BREAK: { *should = true; break; - + } // Skip past the "Save?" window when dying and go to the "Continue?" screen immediately. case VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH: { PauseContext* pauseCtx = static_cast(optionalArg); @@ -612,13 +621,17 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } + // Prevent saving case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. case VB_BE_ABLE_TO_OPEN_DOORS: + // There's no heart containers in boss rush case VB_SPAWN_HEART_CONTAINER: - case VB_RENDER_RUPEE_COUNTER: + // Rupees are useless in boss rush + case VB_RENDER_RUPEE_COUNTER: { *should = false; break; + } } } From 024f1181ee124754891ffa56866bdbe40bfd014b Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:25:59 +0200 Subject: [PATCH 38/48] Update BossRush.cpp --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index f77ab7b38cf..f1b889e9db9 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -588,7 +588,7 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* break; } default: { - SPDLOG_WARNING("[BossRush]: Blue warp spawned in unhandled scene, ignoring"); + SPDLOG_WARN("[BossRush]: Blue warp spawned in unhandled scene, ignoring"); return; } } @@ -632,6 +632,10 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* *should = false; break; } + // Prevent warning spam + default: { + break; + } } } From fd470c1295989b5510d58fc0a1d2bfa67f5bac4c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:39:45 +0200 Subject: [PATCH 39/48] Fix my stupidity --- .../Enhancements/randomizer/hook_handlers.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index efa7520846f..aa7702a850c 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1786,18 +1786,17 @@ void RandomizerOnPlayerUpdateHandler() { //if you void out in water temple without swim you get instantly kicked out to prevent softlocks if (gPlayState->sceneNum == SCENE_WATER_TEMPLE) { GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_2));//lake hylia from water temple - return; - } + } else { + if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { + SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); - if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { - SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); + Play_SetupRespawnPoint(gPlayState, RESPAWN_MODE_DOWN, 0xDFF); + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = respawnInfo->pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw; + } - Play_SetupRespawnPoint(gPlayState, RESPAWN_MODE_DOWN, 0xDFF); - gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = respawnInfo->pos; - gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw; + Play_TriggerVoidOut(gPlayState); } - - Play_TriggerVoidOut(gPlayState); } // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. From c06f1553dbfd1b91ba454d8e0e12d37607ee71fa Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:13:53 +0200 Subject: [PATCH 40/48] Fix #4327 --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index aa7702a850c..9c3f5218ccc 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1739,7 +1739,7 @@ std::map swimSpecialRespawnInfo = { }, { ENTR_HYRULE_FIELD_14,//zr to hf in water - { { 5830.209, -92.16, 3925.911 }, -20025 } + { { 5730.209, -20, 3725.911 }, -20025 } }, { ENTR_LOST_WOODS_7,//zr to lw @@ -1772,7 +1772,11 @@ std::map swimSpecialRespawnInfo = { { ENTR_GERUDO_VALLEY_1,//caught by gerudos as child { { -424, -2051, -74 }, 16384 } - } + }, + { + ENTR_HYRULE_FIELD_7,//hf from mk (can be a problem when it then turns night) + { { 0, 0, 1100 }, 0 } + }, }; f32 triforcePieceScale; From 9ccb8d2754836c3b3967cf92d1f85684b70bc5c3 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:21:50 +0200 Subject: [PATCH 41/48] Update hook_handlers.cpp --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9c3f5218ccc..e707a292f14 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1774,9 +1774,13 @@ std::map swimSpecialRespawnInfo = { { { -424, -2051, -74 }, 16384 } }, { - ENTR_HYRULE_FIELD_7,//hf from mk (can be a problem when it then turns night) + ENTR_HYRULE_FIELD_7,//mk to hf (can be a problem when it then turns night) { { 0, 0, 1100 }, 0 } }, + { + ENTR_ZORAS_FOUNTAIN_0,//jabu blue warp to zf + { { -1580, 150, 1670 }, 8000 } + }, }; f32 triforcePieceScale; From 257ffa7a425226eb16fc42b8ab98874611134841 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:58:38 +0200 Subject: [PATCH 42/48] Fix blue warps --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 5 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 164 +++++++++++------- 2 files changed, 106 insertions(+), 63 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index f1b889e9db9..412c8cd7b60 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -252,10 +252,13 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // Ganondork } else if (warpPosX == -199 && warpPosZ == 0) { play->nextEntranceIndex = ENTR_GANONDORF_BOSS_0; + } else { + SPDLOG_ERROR("[BossRush]: Unknown blue warp in chamber of sages at position ({}, {}). Warping back to chamber of sages.", warpPosX, warpPosZ); + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; } // If coming from a boss room, teleport back to Chamber of Sages and set flag. } else { - play->nextEntranceIndex = SCENE_HAIRAL_NIWA2; + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; if (CheckDungeonCount() == 3) { play->linkAgeOnLoad = LINK_AGE_ADULT; diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 081ff5daa90..311f4d2d445 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -533,11 +533,15 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) { Item_Give(play, ITEM_GORON_RUBY); } - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; + } } else { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; - gSaveContext.nextCutsceneIndex = 0; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; + gSaveContext.nextCutsceneIndex = 0; + } } } else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD), EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { @@ -546,15 +550,21 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_KOKIRI_EMERALD)) { Item_Give(play, ITEM_KOKIRI_EMERALD); } - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; + } } else { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; - gSaveContext.nextCutsceneIndex = 0; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; + gSaveContext.nextCutsceneIndex = 0; + } } } else if (play->sceneNum == SCENE_JABU_JABU_BOSS) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; - gSaveContext.nextCutsceneIndex = 0; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + gSaveContext.nextCutsceneIndex = 0; + } } if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || @@ -562,10 +572,12 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { Entrance_OverrideBlueWarp(); } - osSyncPrintf("\n\n\nおわりおわり"); - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + osSyncPrintf("\n\n\nおわりおわり"); + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; + } } Math_StepToF(&this->unk_194, 2.0f, 0.01f); @@ -650,17 +662,23 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_ZORA_SAPPHIRE)) { Item_Give(play, ITEM_ZORA_SAPPHIRE); } - gSaveContext.nextCutsceneIndex = 0xFFF0; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + gSaveContext.nextCutsceneIndex = 0xFFF0; + } + } + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; } - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { Entrance_OverrideBlueWarp(); } - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; + } } Math_StepToF(&this->unk_194, 2.0f, 0.01f); @@ -758,23 +776,27 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { } this->warpTimer++; - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF, this)) { + if (this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF) { if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) { Item_Give(play, ITEM_MEDALLION_FOREST); } - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; + } } else { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; - } else { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; + } else { + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + } + gSaveContext.nextCutsceneIndex = 0; } - gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_FIRE_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { @@ -782,15 +804,19 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) { Item_Give(play, ITEM_MEDALLION_FIRE); } - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; - gSaveContext.nextCutsceneIndex = 0xFFF3; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + gSaveContext.nextCutsceneIndex = 0xFFF3; + } } else { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; - } else { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; + } else { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; + } + gSaveContext.nextCutsceneIndex = 0; } - gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_WATER_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { @@ -798,16 +824,20 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_WATER)) { Item_Give(play, ITEM_MEDALLION_WATER); } - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; + } } else { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; - } else { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; + } else { + play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; + } + gSaveContext.nextCutsceneIndex = 0; } - gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) { @@ -815,16 +845,20 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) { Item_Give(play, ITEM_MEDALLION_SPIRIT); } - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; + } } else { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; - } else { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; + } else { + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; + } + gSaveContext.nextCutsceneIndex = 0; } - gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) { @@ -832,23 +866,29 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) { Item_Give(play, ITEM_MEDALLION_SHADOW); } - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; + } } else { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_GRAVEYARD_7; - } else { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_GRAVEYARD_7; + } else { + play->nextEntranceIndex = ENTR_GRAVEYARD_8; + } + gSaveContext.nextCutsceneIndex = 0; } - gSaveContext.nextCutsceneIndex = 0; } } - } - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; + if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; + } + } if (this->warpTimer >= 141) { f32 screenFillAlpha; From 70b69b8eea460e5f4e51c0aa8180928cb349ff12 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:02:54 +0200 Subject: [PATCH 43/48] Use ultralib types & clean header --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 22 ++++++++++----------- soh/soh/Enhancements/boss-rush/BossRush.h | 17 +++++++--------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 412c8cd7b60..ae4412d7c81 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -126,15 +126,15 @@ BossRushSetting BossRushOptions[BOSSRUSH_OPTIONS_AMOUNT] = { } }; -const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language) { +const char* BossRush_GetSettingName(u8 optionIndex, u8 language) { return BossRushOptions[optionIndex].name[language].c_str(); } -const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language) { +const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language) { return BossRushOptions[optionIndex].choices[choiceIndex][language].c_str(); } -uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex) { +u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) { return BossRushOptions[optionIndex].choices.size(); } @@ -182,7 +182,7 @@ void BossRush_SpawnBlueWarps(PlayState* play) { } } -void BossRush_SetEquipment(uint8_t linkAge) { +void BossRush_SetEquipment(u8 linkAge) { std::array brButtonItems; std::array brCButtonSlots; @@ -361,7 +361,7 @@ void BossRush_InitSave() { } // Set health - uint16_t health = 16; + u16 health = 16; switch (gSaveContext.bossRushOptions[BR_OPTIONS_HEARTS]) { case BR_CHOICE_HEARTS_7: health *= 7; @@ -471,7 +471,7 @@ void BossRush_InitSave() { } // Upgrades - uint8_t upgradeLevel = 1; + u8 upgradeLevel = 1; if (gSaveContext.bossRushOptions[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) { upgradeLevel = 3; } @@ -661,7 +661,7 @@ void BossRush_OnActorInitHandler(void* actorRef) { } } -void BossRush_OnSceneInitHandler(int16_t sceneNum) { +void BossRush_OnSceneInitHandler(s16 sceneNum) { // Unpause the timer when the scene loaded isn't the Chamber of Sages. if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { gSaveContext.isBossRushPaused = 0; @@ -673,10 +673,10 @@ void BossRush_OnBossDefeatHandler(void* refActor) { } void BossRush_RegisterHooks() { - static uint32_t onVanillaBehaviorHook = 0; - static uint32_t onSceneInitHook = 0; - static uint32_t onActorInitHook = 0; - static uint32_t onBossDefeatHook = 0; + static u32 onVanillaBehaviorHook = 0; + static u32 onSceneInitHook = 0; + static u32 onActorInitHook = 0; + static u32 onBossDefeatHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); diff --git a/soh/soh/Enhancements/boss-rush/BossRush.h b/soh/soh/Enhancements/boss-rush/BossRush.h index 0ae0f4924dd..292cbaf26ad 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -1,19 +1,16 @@ #pragma once -#include "BossRushTypes.h" -#include "variables.h" +#include "z64.h" #ifdef __cplusplus extern "C" { #endif -void BossRush_SpawnBlueWarps(PlayState* play); -void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ); -void BossRush_HandleBlueWarpHeal(PlayState* play); -void BossRush_InitSave(); -const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language); -const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language); -uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex); -void BossRush_RegisterHooks(); + void BossRush_HandleBlueWarpHeal(PlayState* play); + void BossRush_InitSave(); + const char* BossRush_GetSettingName(u8 optionIndex, u8 language); + const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language); + u8 BossRush_GetSettingOptionsAmount(u8 optionIndex); + void BossRush_RegisterHooks(); #ifdef __cplusplus }; #endif From 8607cf012d04845c40e1aae2c28a6483f010e893 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:03:39 +0200 Subject: [PATCH 44/48] Replace options amount macro with BR_OPTIONS_MAX --- soh/include/z64save.h | 2 +- soh/soh/Enhancements/boss-rush/BossRush.cpp | 2 +- soh/soh/Enhancements/boss-rush/BossRushTypes.h | 4 ++-- soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 617c2acf526..c37b79ecfe6 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -275,7 +275,7 @@ typedef struct { /* */ u16 pendingSaleMod; /* */ uint8_t questId; /* */ uint32_t isBossRushPaused; - /* */ uint8_t bossRushOptions[BOSSRUSH_OPTIONS_AMOUNT]; + /* */ uint8_t bossRushOptions[BR_OPTIONS_MAX]; /* */ u8 pendingIceTrapCount; /* */ SohStats sohStats; /* */ FaroresWindData backupFW; diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index ae4412d7c81..56d4c01fb92 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -27,7 +27,7 @@ typedef struct BossRushSetting { std::vector> choices; } BossRushSetting; -BossRushSetting BossRushOptions[BOSSRUSH_OPTIONS_AMOUNT] = { +BossRushSetting BossRushOptions[BR_OPTIONS_MAX] = { { { "BOSSES:", "BOSSE:", "BOSS:" }, { diff --git a/soh/soh/Enhancements/boss-rush/BossRushTypes.h b/soh/soh/Enhancements/boss-rush/BossRushTypes.h index e39cba997a9..cf4d3aaba19 100644 --- a/soh/soh/Enhancements/boss-rush/BossRushTypes.h +++ b/soh/soh/Enhancements/boss-rush/BossRushTypes.h @@ -1,6 +1,5 @@ #pragma once -#define BOSSRUSH_OPTIONS_AMOUNT 12 #define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6 typedef enum { @@ -15,7 +14,8 @@ typedef enum { BR_OPTIONS_LONGSHOT, BR_OPTIONS_HOVERBOOTS, BR_OPTIONS_BUNNYHOOD, - BR_OPTIONS_TIMER + BR_OPTIONS_TIMER, + BR_OPTIONS_MAX, } BossRushOptionEnums; typedef enum { diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index caf684ec22a..3814eff2410 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -1388,7 +1388,7 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { // Move down if (this->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) { // When selecting past the last option, cycle back to the first option. - if ((this->bossRushIndex + 1) > BOSSRUSH_OPTIONS_AMOUNT - 1) { + if ((this->bossRushIndex + 1) > BR_OPTIONS_MAX - 1) { this->bossRushIndex = 0; this->bossRushOffset = 0; } else { @@ -1401,7 +1401,7 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { } else if (this->stickRelY > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP))) { // When selecting past the first option, cycle back to the last option and offset the list to view it properly. if ((this->bossRushIndex - 1) < 0) { - this->bossRushIndex = BOSSRUSH_OPTIONS_AMOUNT - 1; + this->bossRushIndex = BR_OPTIONS_MAX - 1; this->bossRushOffset = this->bossRushIndex - BOSSRUSH_MAX_OPTIONS_ON_SCREEN + 1; } else { // When first visible option is selected when moving up, offset the list up by one. @@ -2306,7 +2306,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { (arrowUpY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11)); } // Arrow down - if (BOSSRUSH_OPTIONS_AMOUNT - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) { + if (BR_OPTIONS_MAX - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) { uint16_t arrowDownX = 140; uint16_t arrowDownY = 181 + (this->bossRushArrowOffset / 10); gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowDownTex, G_IM_FMT_IA, From df79a30697b888ceb87df0d0f849c31736e92400 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:01:38 +0200 Subject: [PATCH 45/48] Remove unused includes --- soh/soh/SaveManager.cpp | 1 - soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c | 1 - 2 files changed, 2 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 448a8d2e06f..e0b87d3791d 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -13,7 +13,6 @@ #include "functions.h" #include "macros.h" #include -#include "soh/Enhancements/boss-rush/BossRush.h" #include #include "SohGui.hpp" diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 1c494fb78b2..f4c227a290f 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -11,7 +11,6 @@ #include "assets/scenes/dungeons/ganon_boss/ganon_boss_scene.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/boss-rush/BossRushTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include From dace9135ffd4d48d421ea88dd835024cbefc42c5 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:34:39 +0200 Subject: [PATCH 46/48] Remove accidental line doubling --- soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index 5464b962417..a30091ad3db 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -783,7 +783,6 @@ void BossFd2_Death(BossFd2* this, PlayState* play) { if (bossFd->work[BFD_ACTION_STATE] == BOSSFD_SKULL_BURN) { this->deathState = DEATH_FINISH; mainCam->eye = this->camData.eye; - mainCam->eye = this->camData.eye; mainCam->eyeNext = this->camData.eye; mainCam->at = this->camData.at; func_800C08AC(play, this->deathCamera, 0); From ccc3f55c847e6a468c21c8974b37db6f31d6e6d3 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 2 Oct 2024 04:42:06 -0500 Subject: [PATCH 47/48] Tweaks to boss rush (#6) --- soh/soh/Enhancements/boss-rush/BossRush.cpp | 12 ++ .../Enhancements/randomizer/hook_handlers.cpp | 9 - .../actors/ovl_Door_Warp1/z_door_warp1.c | 161 +++++++----------- 3 files changed, 72 insertions(+), 110 deletions(-) diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 56d4c01fb92..51fd4db27d6 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -672,22 +672,33 @@ void BossRush_OnBossDefeatHandler(void* refActor) { BossRush_HandleCompleteBoss(gPlayState); } +void BossRush_OnBlueWarpUpdate(void* actor) { + DoorWarp1* blueWarp = static_cast(actor); + + if (blueWarp->warpTimer > 160) { + BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); + } +} + void BossRush_RegisterHooks() { static u32 onVanillaBehaviorHook = 0; static u32 onSceneInitHook = 0; static u32 onActorInitHook = 0; static u32 onBossDefeatHook = 0; + static u32 onActorUpdate = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); GameInteractor::Instance->UnregisterGameHook(onBossDefeatHook); + GameInteractor::Instance->UnregisterGameHookForID(onActorUpdate); onVanillaBehaviorHook = 0; onSceneInitHook = 0; onActorInitHook = 0; onBossDefeatHook = 0; + onActorUpdate = 0; if (!IS_BOSS_RUSH) return; @@ -695,5 +706,6 @@ void BossRush_RegisterHooks() { onSceneInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); onBossDefeatHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnBossDefeatHandler); + onActorUpdate = GameInteractor::Instance->RegisterGameHookForID(ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate); }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index b20ba4c9496..9150c3d1e94 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1239,15 +1239,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = INV_CONTENT((RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) ? ITEM_BOMBCHU : ITEM_BOMB)) != ITEM_NONE; break; } - case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { - if ( - RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || - RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF - ) { - Entrance_OverrideBlueWarp(); - } - break; - } case VB_TRADE_TIMER_ODD_MUSHROOM: case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 6b236c4b03a..be1756613ed 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -533,15 +533,11 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) { Item_Give(play, ITEM_GORON_RUBY); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; - } + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; - gSaveContext.nextCutsceneIndex = 0; - } + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; + gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD), EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) { @@ -550,29 +546,21 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_KOKIRI_EMERALD)) { Item_Give(play, ITEM_KOKIRI_EMERALD); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; - gSaveContext.nextCutsceneIndex = 0xFFF1; - } + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; + gSaveContext.nextCutsceneIndex = 0xFFF1; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; - gSaveContext.nextCutsceneIndex = 0; - } - } - } else if (play->sceneNum == SCENE_JABU_JABU_BOSS) { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; gSaveContext.nextCutsceneIndex = 0; } + } else if (play->sceneNum == SCENE_JABU_JABU_BOSS) { + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + gSaveContext.nextCutsceneIndex = 0; } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - osSyncPrintf("\n\n\nおわりおわり"); - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - } + osSyncPrintf("\n\n\nおわりおわり"); + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; } Math_StepToF(&this->unk_194, 2.0f, 0.01f); @@ -657,18 +645,12 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_ZORA_SAPPHIRE)) { Item_Give(play, ITEM_ZORA_SAPPHIRE); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - gSaveContext.nextCutsceneIndex = 0xFFF0; - } - } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + gSaveContext.nextCutsceneIndex = 0xFFF0; } + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; - } + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; } Math_StepToF(&this->unk_194, 2.0f, 0.01f); @@ -773,20 +755,16 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) { Item_Give(play, ITEM_MEDALLION_FOREST); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; - } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; - } else { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; - } - gSaveContext.nextCutsceneIndex = 0; + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; + } else { + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; } + gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_FIRE_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { @@ -794,19 +772,15 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) { Item_Give(play, ITEM_MEDALLION_FIRE); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; - gSaveContext.nextCutsceneIndex = 0xFFF3; - } + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + gSaveContext.nextCutsceneIndex = 0xFFF3; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; - } else { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; - } - gSaveContext.nextCutsceneIndex = 0; + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; + } else { + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; } + gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_WATER_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { @@ -814,20 +788,16 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_WATER)) { Item_Give(play, ITEM_MEDALLION_WATER); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; - } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; - } else { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; - } - gSaveContext.nextCutsceneIndex = 0; + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; + } else { + play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; } + gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) { @@ -835,20 +805,16 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) { Item_Give(play, ITEM_MEDALLION_SPIRIT); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; - } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; - } else { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; - } - gSaveContext.nextCutsceneIndex = 0; + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; + } else { + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; } + gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) { @@ -856,30 +822,23 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) { Item_Give(play, ITEM_MEDALLION_SHADOW); } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0; - gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; - } + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } else { - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_GRAVEYARD_7; - } else { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; - } - gSaveContext.nextCutsceneIndex = 0; + if (!LINK_IS_ADULT) { + play->nextEntranceIndex = ENTR_GRAVEYARD_7; + } else { + play->nextEntranceIndex = ENTR_GRAVEYARD_8; } + gSaveContext.nextCutsceneIndex = 0; } } - if (GameInteractor_Should(VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, true, this)) { - play->transitionTrigger = TRANS_TRIGGER_START; - play->transitionType = TRANS_TYPE_FADE_WHITE; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; - } + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; } - if (this->warpTimer >= 141) { f32 screenFillAlpha; From a15763fc22091d357c2d7dc20e70b350a978ca6c Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:47:31 +0200 Subject: [PATCH 48/48] Update GameInteractor_HookTable.h --- soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index a3fc284eef9..5669da66195 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -24,6 +24,7 @@ DEFINE_HOOK(OnActorInit, (void* actor)); DEFINE_HOOK(OnActorUpdate, (void* actor)); DEFINE_HOOK(OnActorKill, (void* actor)); DEFINE_HOOK(OnEnemyDefeat, (void* actor)); +DEFINE_HOOK(OnBossDefeat, (void* actor)); DEFINE_HOOK(OnPlayerBonk, ()); DEFINE_HOOK(OnPlayDestroy, ()); DEFINE_HOOK(OnPlayDrawEnd, ());