From 1d20000411c120d81144c736f81e5552498a3e77 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 28 Jul 2025 08:54:31 -0700 Subject: [PATCH 01/98] MPQ Support LUS Bump (#5570) * Adapt to changes to LUS regarding including MPQ support. * CMake compile definitions are stupid. * Don't manually close O2RArchive. * Finish LUS bump, including SoH-side fix for font free crash. --- CMakeLists.txt | 4 ++++ libultraship | 2 +- soh/soh/OTRGlobals.cpp | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3324b7c00..ef00ae8f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,9 @@ set(GFX_DEBUG_DISASSEMBLER ON) set(GBI_UCODE F3DEX_GBI_2) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") +# Enable MPQ and OTR support +set(INCLUDE_MPQ_SUPPORT ON) + ################################################################################ # Set CONTROLLERBUTTONS_T ################################################################################ @@ -165,6 +168,7 @@ add_compile_definitions(CONTROLLERBUTTONS_T=uint32_t) ################################################################################ add_subdirectory(libultraship ${CMAKE_BINARY_DIR}/libultraship) target_compile_options(libultraship PRIVATE "${WARNING_OVERRIDE}") +target_compile_definitions(libultraship PUBLIC INCLUDE_MPQ_SUPPORT) add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) add_subdirectory(OTRExporter) add_subdirectory(soh) diff --git a/libultraship b/libultraship index 6a3f6cd32..7f737f8be 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 6a3f6cd327b99f617b623e5b9a3afeae460aac2b +Subproject commit 7f737f8be9580980f5a1fe7784d6e1045f0309da diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index bc9b3106e..d59871d54 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -984,7 +984,6 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { version.minor = reader->ReadUInt16(); version.patch = reader->ReadUInt16(); } - archive->Close(); } return version; @@ -1679,7 +1678,9 @@ ImFont* OTRGlobals::CreateFontWithSize(float size, std::string fontPath) { initData->Path = fontPath; std::shared_ptr fontData = std::static_pointer_cast( Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); - font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size); + ImFontConfig fontConf; + fontConf.FontDataOwnedByAtlas = false; + font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size, &fontConf); } // FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly float iconFontSize = size * 2.0f / 3.0f; From be77a9be713b669a715e1006e78484e469258e4c Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 29 Jul 2025 18:47:43 -0700 Subject: [PATCH 02/98] Fix Dpad Navigation and Dpad equips on Inventory (#5708) * Encapsulates ship-specific stuff inside the first state checks in menu draw functions to prevent function bleed. * clang --- .../ovl_kaleido_scope/z_kaleido_collect.c | 113 +++++++++--------- .../ovl_kaleido_scope/z_kaleido_equipment.c | 9 +- .../misc/ovl_kaleido_scope/z_kaleido_item.c | 11 +- .../ovl_kaleido_scope/z_kaleido_map_PAL.c | 2 +- 4 files changed, 69 insertions(+), 66 deletions(-) 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 78a072c6f..ade62acc3 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 @@ -8,51 +8,6 @@ extern const char* digitTextures[]; void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { - Color_RGB8 aButtonColor = { 80, 150, 255 }; - if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) { - aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor); - } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { - aButtonColor = (Color_RGB8){ 80, 255, 150 }; - } - if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true)) { - aButtonColor = (Color_RGB8){ 191, 191, 191 }; - } - - Color_RGB8 cButtonsColor = { 255, 255, 50 }; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) { - cButtonsColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); - } - Color_RGB8 cUpButtonColor = cButtonsColor; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { - cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); - } - if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true)) { - cUpButtonColor = (Color_RGB8){ 191, 191, 191 }; - } - - Color_RGB8 cDownButtonColor = cButtonsColor; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { - cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); - } - if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true)) { - cDownButtonColor = (Color_RGB8){ 191, 191, 191 }; - } - - Color_RGB8 cLeftButtonColor = cButtonsColor; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { - cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); - } - if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true)) { - cLeftButtonColor = (Color_RGB8){ 191, 191, 191 }; - } - - Color_RGB8 cRightButtonColor = cButtonsColor; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { - cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); - } - if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true)) { - cRightButtonColor = (Color_RGB8){ 191, 191, 191 }; - } static s16 D_8082A070[][4] = { { 255, 0, 0, 255 }, @@ -124,22 +79,22 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { s16 pad2; s16 phi_s0_2; s16 sp208[3]; - if (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0)) { - if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { - pauseCtx->stickRelX = -35; - } else if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { - pauseCtx->stickRelX = 35; - } else if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { - pauseCtx->stickRelY = -35; - } else if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) { - pauseCtx->stickRelY = 35; - } - } OPEN_DISPS(gfxCtx); if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && (pauseCtx->pageIndex == PAUSE_QUEST)) { + if (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0)) { + if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { + pauseCtx->stickRelX = -35; + } else if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { + pauseCtx->stickRelX = 35; + } else if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { + pauseCtx->stickRelY = -35; + } else if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) { + pauseCtx->stickRelY = 35; + } + } pauseCtx->cursorColorSet = 0; if (pauseCtx->cursorSpecialPos == 0) { @@ -516,6 +471,52 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { } if (pauseCtx->state == 6) { + Color_RGB8 aButtonColor = { 80, 150, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) { + aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor); + } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { + aButtonColor = (Color_RGB8){ 80, 255, 150 }; + } + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true)) { + aButtonColor = (Color_RGB8){ 191, 191, 191 }; + } + + Color_RGB8 cButtonsColor = { 255, 255, 50 }; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) { + cButtonsColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + } + Color_RGB8 cUpButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { + cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); + } + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true)) { + cUpButtonColor = (Color_RGB8){ 191, 191, 191 }; + } + + Color_RGB8 cDownButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { + cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); + } + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true)) { + cDownButtonColor = (Color_RGB8){ 191, 191, 191 }; + } + + Color_RGB8 cLeftButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { + cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); + } + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true)) { + cLeftButtonColor = (Color_RGB8){ 191, 191, 191 }; + } + + Color_RGB8 cRightButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { + cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); + } + if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true)) { + cRightButtonColor = (Color_RGB8){ 191, 191, 191 }; + } + gDPPipeSync(POLY_OPA_DISP++); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index aa18912ea..cec05af72 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -183,10 +183,6 @@ void KaleidoScope_DrawEquipment(PlayState* play) { s16 cursorX; s16 cursorY; s16 oldCursorPoint; - bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP)); - bool pauseAnyCursor = - (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) || - (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON); OPEN_DISPS(play->state.gfxCtx); @@ -204,6 +200,11 @@ void KaleidoScope_DrawEquipment(PlayState* play) { } if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_EQUIP)) { + bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP)); + bool pauseAnyCursor = + (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) || + (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON); + oldCursorPoint = pauseCtx->cursorPoint[PAUSE_EQUIP]; pauseCtx->cursorColorSet = 0; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index beef301c4..7f0cfcc7a 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -421,11 +421,6 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { s16 cursorY; s16 oldCursorPoint; s16 moveCursorResult; - bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP)); - bool pauseAnyCursor = - pauseCtx->cursorSpecialPos == 0 && - ((CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) || - (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON)); OPEN_DISPS(play->state.gfxCtx); @@ -437,6 +432,12 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->nameColorSet = 0; if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_ITEM)) { + bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP)); + bool pauseAnyCursor = + pauseCtx->cursorSpecialPos == 0 && + ((CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) || + (CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON)); + moveCursorResult = 0 || IsItemCycling(); oldCursorPoint = pauseCtx->cursorPoint[PAUSE_ITEM]; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c index 3ff61d783..3e79eb6ad 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c @@ -59,11 +59,11 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) { s16 stepG; s16 stepB; u16 rgba16; - bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); OPEN_DISPS(gfxCtx); if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_MAP)) { + bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); pauseCtx->cursorColorSet = 0; oldCursorPoint = pauseCtx->cursorPoint[PAUSE_MAP]; From 429021d43471ce89b69c24028a8a3ea19eb73828 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 5 Aug 2025 18:28:19 -0700 Subject: [PATCH 03/98] Add `THRescuedAllCarpenters` to reset list to prevent seed bleed of bridge. (#5725) --- soh/soh/Enhancements/randomizer/logic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..3c0c8345e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2471,6 +2471,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { THCouldFreeDoubleCellCarpenter = false; TH_CouldFreeDeadEndCarpenter = false; THCouldRescueSlopeCarpenter = false; + THRescuedAllCarpenters = false; GF_GateOpen = false; GtG_GateOpen = false; DampesWindmillAccess = false; From b87f1432fd245ce3409fbc769f17e8e94d69db24 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Wed, 6 Aug 2025 04:43:19 +0100 Subject: [PATCH 04/98] properly clear location subcatagories when generating a seed (#5707) --- soh/soh/Enhancements/randomizer/context.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index a0f7f223b..243f22ea6 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -161,6 +161,10 @@ bool Context::IsQuestOfLocationActive(RandomizerCheck rc) { void Context::GenerateLocationPool() { allLocations.clear(); + overworldLocations.clear(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + dungeon->locations.clear(); + } for (Location& location : StaticData::GetLocationTable()) { // skip RCs that shouldn't be in the pool for any reason (i.e. settings, unsupported check type, etc.) // TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.) From 6d4c6f8ea649d1e4857a275994e854c8a983dab8 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 6 Aug 2025 05:43:41 +0200 Subject: [PATCH 05/98] Rando: Remove ice trap effect from vanilla ice trap chests (#5711) --- .../game-interactor/vanilla-behavior/GIVanillaBehavior.h | 9 +++++++++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 1 + soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 6 ++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..0ba910cf6 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2222,6 +2222,15 @@ typedef enum { // - `s32` limbCount // - `*Vec3s` frameTable VB_LOAD_PLAYER_ANIMATION_FRAME, + + // #### `result` + // ```c + // (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + // this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100 + // ``` + // #### `args` + // - `*EnBox` + VB_CHEST_USE_ICE_EFFECT, } GIVanillaBehavior; #endif diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index d73cebca7..447125ae1 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1713,6 +1713,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_GIVE_ITEM_WATER_MEDALLION: case VB_GIVE_ITEM_SPIRIT_MEDALLION: case VB_GIVE_ITEM_SHADOW_MEDALLION: + case VB_CHEST_USE_ICE_EFFECT: *should = false; break; case VB_GIVE_ITEM_SKULL_TOKEN: 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 9a3a8fb77..f52b4a458 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 @@ -567,8 +567,10 @@ void EnBox_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->dyna.actor, 40.0f); } - if ((this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && - this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) { + if (GameInteractor_Should(VB_CHEST_USE_ICE_EFFECT, + (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && + this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100, + this)) { EnBox_SpawnIceSmoke(this, play); } } From 89c1c97522763c280226f60fcba85620d26ed5ad Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 9 Aug 2025 11:17:33 -0700 Subject: [PATCH 06/98] Add missing CVar check for tab key processing for alt asset toggle. (#5736) --- soh/soh/OTRGlobals.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 630ffeaaa..aace117a8 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1435,7 +1435,9 @@ extern "C" void Graph_StartFrame() { } #endif case KbScancode::LUS_KB_TAB: { - CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 0)); + if (CVarGetInteger(CVAR_SETTING("Mods.AlternateAssetsHotkey"), 1)) { + CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 0)); + } break; } } From 353ad944be88b969e44faa0619cc5adfed98d561 Mon Sep 17 00:00:00 2001 From: xxAtrain223 Date: Tue, 12 Aug 2025 21:55:38 -0500 Subject: [PATCH 07/98] Removed SHUTTER_BACK_LOCKED and SHUTTER_BOSS from GetDungeonSmallKeyDoors. (#5738) --- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 710437dc6..a9e7264a0 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2228,7 +2228,7 @@ const std::vector& GetDungeonSmallKeyDoors(SceneID sceneId) { } } else if (transitionActor.id == ACTOR_DOOR_SHUTTER) { uint8_t doorType = (transitionActor.params >> 7) & 15; - if (doorType == SHUTTER_BACK_LOCKED || doorType == SHUTTER_BOSS || doorType == SHUTTER_KEY_LOCKED) { + if (doorType == SHUTTER_KEY_LOCKED) { dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F); } } From e104870e6ad6fb1e6c9600d6c0d9691d9a53b0e5 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:56:07 -0400 Subject: [PATCH 08/98] remove !IS_RANDO check (#5728) --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 9a602323d..b847fca51 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -941,7 +941,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } - if (actor->id == ACTOR_EN_JJ && !IS_RANDO) { + if (actor->id == ACTOR_EN_JJ) { enJjUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); From 3e39a940833eb0d984fe4bb361a8856e8a2d1c1e Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 13 Aug 2025 04:56:52 +0200 Subject: [PATCH 09/98] Turn song text into a notification (#5712) --- soh/soh/Enhancements/audio/AudioCollection.cpp | 9 +++++++++ soh/soh/Enhancements/audio/AudioCollection.h | 1 + soh/soh/Enhancements/mods.cpp | 1 - soh/soh/OTRGlobals.cpp | 9 --------- soh/soh/OTRGlobals.h | 2 -- soh/src/code/audio_load.c | 6 ++---- 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index d3f69dad8..a30d3f086 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -2,6 +2,7 @@ #include "sequence.h" #include "sfx.h" #include "soh/cvar_prefixes.h" +#include "soh/Notification/Notification.h" #include #include #include @@ -458,3 +459,11 @@ extern "C" bool AudioCollection_HasSequenceNum(uint16_t seqId) { extern "C" size_t AudioCollection_SequenceMapSize() { return AudioCollection::Instance->SequenceMapSize(); } + +extern "C" void AudioCollection_EmitSongNameNotification(s32 seqId) { + const char* sequenceName = AudioCollection_GetSequenceName(seqId); + if (sequenceName != NULL) { + Notification::Emit({ .message = "Currently playing: " + std::string(sequenceName), + .remainingTime = (float)CVarGetInteger(CVAR_AUDIO("SeqNameOverlayDuration"), 5) }); + } +} \ No newline at end of file diff --git a/soh/soh/Enhancements/audio/AudioCollection.h b/soh/soh/Enhancements/audio/AudioCollection.h index 2cdb02e21..51a6902cf 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.h +++ b/soh/soh/Enhancements/audio/AudioCollection.h @@ -73,4 +73,5 @@ void AudioCollection_AddToCollection(char* otrPath, uint16_t seqNum); const char* AudioCollection_GetSequenceName(uint16_t seqId); bool AudioCollection_HasSequenceNum(uint16_t seqId); size_t AudioCollection_SequenceMapSize(); +void AudioCollection_EmitSongNameNotification(s32 seqId); #endif \ No newline at end of file diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 6c547db08..15f85e52a 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -49,7 +49,6 @@ extern "C" { extern SaveContext gSaveContext; extern PlayState* gPlayState; -extern void Overlay_DisplayText(float duration, const char* text); } // GreyScaleEndDlist diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d59871d54..7d2194cca 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2580,15 +2580,6 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { return false; } -extern "C" void Overlay_DisplayText(float duration, const char* text) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(duration, true, text); -} - -extern "C" void Overlay_DisplayText_Seconds(int seconds, const char* text) { - float duration = seconds * OTRGlobals::Instance->GetInterpolationFPS() * 0.05; - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(duration, true, text); -} - extern "C" void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex) { SetCurrentGrottoIDForTracker(entranceIndex); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index cab7575cd..032686f8e 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -156,8 +156,6 @@ void Randomizer_SetSpoilerLoaded(bool spoilerLoaded); uint8_t Randomizer_GenerateRandomizer(); void Randomizer_ShowRandomizerMenu(); int CustomMessage_RetrieveIfExists(PlayState* play); -void Overlay_DisplayText(float duration, const char* text); -void Overlay_DisplayText_Seconds(int seconds, const char* text); GetItemEntry ItemTable_Retrieve(int16_t getItemID); GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex); diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index 81f67f9c0..52efa4016 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -640,10 +640,8 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { if (gPlayState != NULL) { previousSceneNum = gPlayState->sceneNum; } - const char* sequenceName = AudioCollection_GetSequenceName(seqId); - if (sequenceName != NULL) { - Overlay_DisplayText_Seconds(CVarGetInteger(CVAR_AUDIO("SeqNameOverlayDuration"), 5), sequenceName); - } + + AudioCollection_EmitSongNameNotification(seqId); } } From 526d221c56d99b5ab0715784205b562037be1750 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 13 Aug 2025 04:57:02 +0200 Subject: [PATCH 10/98] Add timestamps for remaining custom rando items (#5713) --- soh/soh/Enhancements/gameplaystats.h | 45 +++++++++++++- .../Enhancements/randomizer/randomizer.cpp | 58 +++++++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 1f89cb3a4..1d60b5dfc 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -51,9 +51,48 @@ typedef enum { /* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c /* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c /* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c - /* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c - /* 0xAB */ TIMESTAMP_MAX - + /* 0xAB */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c + /* 0xAC */ TIMESTAMP_FOUND_GOHMA_SOUL, + /* 0xAD */ TIMESTAMP_FOUND_KING_DODONGO_SOUL, + /* 0xAE */ TIMESTAMP_FOUND_BARINADE_SOUL, + /* 0xAF */ TIMESTAMP_FOUND_PHANTOM_GANON_SOUL, + /* 0xB0 */ TIMESTAMP_FOUND_VOLVAGIA_SOUL, + /* 0xB1 */ TIMESTAMP_FOUND_MORPHA_SOUL, + /* 0xB2 */ TIMESTAMP_FOUND_BONGO_BONGO_SOUL, + /* 0xB3 */ TIMESTAMP_FOUND_TWINROVA_SOUL, + /* 0xB5 */ TIMESTAMP_FOUND_GANON_SOUL, + /* 0xB6 */ TIMESTAMP_FOUND_BRONZE_SCALE, + /* 0xB7 */ TIMESTAMP_FOUND_OCARINA_A_BUTTON, + /* 0xB8 */ TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON, + /* 0xB9 */ TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON, + /* 0xBA */ TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON, + /* 0xBB */ TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON, + /* 0xBC */ TIMESTAMP_FOUND_FISHING_POLE, + /* 0xBD */ TIMESTAMP_FOUND_GUARD_HOUSE_KEY, + /* 0xBE */ TIMESTAMP_FOUND_MARKET_BAZAAR_KEY, + /* 0xBF */ TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY, + /* 0xC0 */ TIMESTAMP_FOUND_MASK_SHOP_KEY, + /* 0xC1 */ TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY, + /* 0xC2 */ TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY, + /* 0xC3 */ TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY, + /* 0xC4 */ TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY, + /* 0xC5 */ TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY, + /* 0xC6 */ TIMESTAMP_FOUND_ALLEY_HOUSE_KEY, + /* 0xC7 */ TIMESTAMP_FOUND_KAK_BAZAAR_KEY, + /* 0xC8 */ TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY, + /* 0xC9 */ TIMESTAMP_FOUND_BOSS_HOUSE_KEY, + /* 0xCA */ TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY, + /* 0xCB */ TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY, + /* 0xCC */ TIMESTAMP_FOUND_IMPAS_HOUSE_KEY, + /* 0xCD */ TIMESTAMP_FOUND_WINDMILL_KEY, + /* 0xCE */ TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY, + /* 0xCF */ TIMESTAMP_FOUND_DAMPES_HUT_KEY, + /* 0xD0 */ TIMESTAMP_FOUND_TALONS_HOUSE_KEY, + /* 0xD1 */ TIMESTAMP_FOUND_STABLES_KEY, + /* 0xD2 */ TIMESTAMP_FOUND_BACK_TOWER_KEY, + /* 0xD3 */ TIMESTAMP_FOUND_HYLIA_LAB_KEY, + /* 0xD4 */ TIMESTAMP_FOUND_FISHING_HOLE_KEY, + /* 0xD5 */ TIMESTAMP_MAX } GameplayStatTimestamp; typedef enum { diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5f9027d82..a5e265142 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5783,6 +5783,53 @@ void RandomizerSettingsWindow::InitElement() { mSettings->UpdateOptionProperties(); } +static std::unordered_map randomizerGetToStatsTimeStamp = { + { RG_GOHMA_SOUL, TIMESTAMP_FOUND_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, TIMESTAMP_FOUND_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, TIMESTAMP_FOUND_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, TIMESTAMP_FOUND_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, TIMESTAMP_FOUND_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, TIMESTAMP_FOUND_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, TIMESTAMP_FOUND_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, TIMESTAMP_FOUND_TWINROVA_SOUL }, + { RG_GANON_SOUL, TIMESTAMP_FOUND_GANON_SOUL }, + + { RG_BRONZE_SCALE, TIMESTAMP_FOUND_BRONZE_SCALE }, + + { RG_OCARINA_A_BUTTON, TIMESTAMP_FOUND_OCARINA_A_BUTTON }, + { RG_OCARINA_C_UP_BUTTON, TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON }, + { RG_OCARINA_C_DOWN_BUTTON, TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON }, + { RG_OCARINA_C_LEFT_BUTTON, TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON }, + { RG_OCARINA_C_RIGHT_BUTTON, TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON }, + + { RG_FISHING_POLE, TIMESTAMP_FOUND_FISHING_POLE }, + + { RG_GUARD_HOUSE_KEY, TIMESTAMP_FOUND_GUARD_HOUSE_KEY }, + { RG_MARKET_BAZAAR_KEY, TIMESTAMP_FOUND_MARKET_BAZAAR_KEY }, + { RG_MARKET_POTION_SHOP_KEY, TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY }, + { RG_MASK_SHOP_KEY, TIMESTAMP_FOUND_MASK_SHOP_KEY }, + { RG_MARKET_SHOOTING_GALLERY_KEY, TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY }, + { RG_BOMBCHU_BOWLING_KEY, TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY }, + { RG_TREASURE_CHEST_GAME_BUILDING_KEY, TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY }, + { RG_BOMBCHU_SHOP_KEY, TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY }, + { RG_RICHARDS_HOUSE_KEY, TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY }, + { RG_ALLEY_HOUSE_KEY, TIMESTAMP_FOUND_ALLEY_HOUSE_KEY }, + { RG_KAK_BAZAAR_KEY, TIMESTAMP_FOUND_KAK_BAZAAR_KEY }, + { RG_KAK_POTION_SHOP_KEY, TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY }, + { RG_BOSS_HOUSE_KEY, TIMESTAMP_FOUND_BOSS_HOUSE_KEY }, + { RG_GRANNYS_POTION_SHOP_KEY, TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY }, + { RG_SKULLTULA_HOUSE_KEY, TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY }, + { RG_IMPAS_HOUSE_KEY, TIMESTAMP_FOUND_IMPAS_HOUSE_KEY }, + { RG_WINDMILL_KEY, TIMESTAMP_FOUND_WINDMILL_KEY }, + { RG_KAK_SHOOTING_GALLERY_KEY, TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY }, + { RG_DAMPES_HUT_KEY, TIMESTAMP_FOUND_DAMPES_HUT_KEY }, + { RG_TALONS_HOUSE_KEY, TIMESTAMP_FOUND_TALONS_HOUSE_KEY }, + { RG_STABLES_KEY, TIMESTAMP_FOUND_STABLES_KEY }, + { RG_BACK_TOWER_KEY, TIMESTAMP_FOUND_BACK_TOWER_KEY }, + { RG_HYLIA_LAB_KEY, TIMESTAMP_FOUND_HYLIA_LAB_KEY }, + { RG_FISHING_HOLE_KEY, TIMESTAMP_FOUND_FISHING_HOLE_KEY }, +}; + // Gameplay stat tracking: Update time the item was acquired // (special cases for rando items) void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { @@ -5797,6 +5844,12 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { // Use ITEM_KEY_BOSS to timestamp Ganon's boss key if (item == RG_GANONS_CASTLE_BOSS_KEY) { gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time; + return; + } + + if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) { + gSaveContext.ship.stats.itemTimestamp[randomizerGetToStatsTimeStamp[(RandomizerGet)item]] = time; + return; } // Count any bottled item as a bottle @@ -5806,6 +5859,7 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { } return; } + // Count any bombchu pack as bombchus if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) { if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = 0) { @@ -5813,11 +5867,15 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { } return; } + if (item == RG_MAGIC_SINGLE) { gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time; + return; } + if (item == RG_DOUBLE_DEFENSE) { gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time; + return; } } From c597e1c4ce78c80c61325912117a918a3b7c03db Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Wed, 13 Aug 2025 04:57:19 +0200 Subject: [PATCH 11/98] TWEAK: SoT Time Travel - Allow Swordless (#5716) * Magic number + more modular * tweak + switch * forgot basic oot * linebreak * c-lang --- soh/soh/Enhancements/enhancementTypes.h | 2 ++ soh/soh/Enhancements/mods.cpp | 23 ++++++++++++++++++++--- soh/soh/SohGui/SohMenuEnhancements.cpp | 6 ++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index c1b91cffa..bd025115b 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -112,7 +112,9 @@ typedef enum { typedef enum { TIME_TRAVEL_DISABLED, TIME_TRAVEL_OOT, + TIME_TRAVEL_OOT_MS, TIME_TRAVEL_ANY, + TIME_TRAVEL_ANY_MS } TimeTravelType; typedef enum { diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 15f85e52a..5fef9befc 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -130,10 +130,27 @@ void RegisterOcarinaTimeTravel() { bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs && !nearbyGossipStone; bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); - bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2; bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); - // TODO: Once Swordless Adult is fixed: Remove the Master Sword check - if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) { + int timeTravelSetting = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0); + bool meetsTimeTravelRequirements = false; + + switch (timeTravelSetting) { + case TIME_TRAVEL_ANY: + meetsTimeTravelRequirements = true; + break; + case TIME_TRAVEL_ANY_MS: + meetsTimeTravelRequirements = hasMasterSword; + break; + case TIME_TRAVEL_OOT_MS: + meetsTimeTravelRequirements = hasMasterSword && hasOcarinaOfTime; + break; + case TIME_TRAVEL_OOT: + default: + meetsTimeTravelRequirements = hasOcarinaOfTime; + break; + } + + if (justPlayedSoT && notNearAnySource && meetsTimeTravelRequirements) { SwitchAge(); } }); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index bdc6f5344..488aeb720 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -56,7 +56,9 @@ static const std::unordered_map chestStyleMatchesContentsO static const std::unordered_map timeTravelOptions = { { TIME_TRAVEL_DISABLED, "Disabled" }, { TIME_TRAVEL_OOT, "Ocarina of Time" }, + { TIME_TRAVEL_OOT_MS, "Ocarina of Time + Master Sword" }, { TIME_TRAVEL_ANY, "Any Ocarina" }, + { TIME_TRAVEL_ANY_MS, "Any Ocarina + Master Sword" }, }; static const std::unordered_map sleepingWaterfallOptions = { @@ -783,9 +785,9 @@ void SohMenu::AddMenuEnhancements() { .Tooltip("Allows Link to freely change age by playing the Song of Time.\n" "Time Blocks can still be used properly.\n\n" "Requirements:\n" - " - Obtained the Ocarina of Time (depends on selection)\n" " - Obtained the Song of Time\n" - " - Obtained the Master Sword\n" + " - Obtained the Ocarina of Time (depends on selection)\n" + " - Obtained the Master Sword (depends on selection)\n" " - Not within range of a Time Block\n" " - Not within range of Ocarina Playing spots")); From 9cdffc080bb3ea8317df1aec8da6b2c38ca6389f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 13 Aug 2025 03:36:51 +0000 Subject: [PATCH 12/98] small typo fixes (#5680) incorrect RR was tripping up my code generator --- soh/soh/CrashHandlerExt.cpp | 2 +- soh/soh/Enhancements/randomizer/ShuffleCrates.cpp | 2 +- .../randomizer/location_access/overworld/gerudo_fortress.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/soh/CrashHandlerExt.cpp b/soh/soh/CrashHandlerExt.cpp index cc9c7b1ee..3ca821460 100644 --- a/soh/soh/CrashHandlerExt.cpp +++ b/soh/soh/CrashHandlerExt.cpp @@ -19,7 +19,7 @@ static std::array sCatToStrArray{ "SWITCH", "BG", "PLAYER", "EXPLOSIVE", "NPC", "ENEMY", "PROP", "ITEMACTION", "MISC", "BOSS", "DOOR", "CHEST", }; -#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName +#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName, static std::array sSceneIdToStrArray{ #include "tables/scene_table.h" diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index 53a65df22..6962b290d 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -336,7 +336,7 @@ void Rando::StaticData::RegisterCrateLocations() { locationTable[RC_GF_SOUTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_SOUTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1534), "Southmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTHMOST_CENTER_CRATE)); locationTable[RC_GF_MID_SOUTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_SOUTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1594), "Middle South Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_SOUTH_CENTER_CRATE)); locationTable[RC_GF_MID_NORTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_NORTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1782), "Middle North Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_NORTH_CENTER_CRATE)); - locationTable[RR_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RR_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE)); + locationTable[RC_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE)); locationTable[RC_GF_OUTSKIRTS_NE_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NE_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-60, -2210), "Outskirts Northeast Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NE_CRATE)); locationTable[RC_GF_OUTSKIRTS_NW_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NW_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-120, -2210), "Outskirts Northwest Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NW_CRATE)); locationTable[RC_GF_HBA_RANGE_CRATE_2] = Location::Crate(RC_GF_HBA_RANGE_CRATE_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(4090, -1780), "Horseback Archery Range Crate 2", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_HBA_RANGE_CRATE_2)); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 3929faf86..17e28d5eb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -30,7 +30,7 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_SOUTHMOST_CENTER_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_MID_SOUTH_CENTER_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_MID_NORTH_CENTER_CRATE, logic->CanBreakCrates()), - LOCATION(RR_GF_NORTHMOST_CENTER_CRATE, logic->CanBreakCrates()), + LOCATION(RC_GF_NORTHMOST_CENTER_CRATE, logic->CanBreakCrates()), }, { //Exits Entrance(RR_TH_1_TORCH_CELL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index a5e265142..b8a4820d8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2332,7 +2332,7 @@ std::map rcToRandomizerInf = { RAND_INF_GF_MID_NORTH_CENTER_CRATE, }, { - RR_GF_NORTHMOST_CENTER_CRATE, + RC_GF_NORTHMOST_CENTER_CRATE, RAND_INF_GF_NORTHMOST_CENTER_CRATE, }, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..c2b9cbbdd 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2396,7 +2396,7 @@ typedef enum { RC_GF_SOUTHMOST_CENTER_CRATE, RC_GF_MID_SOUTH_CENTER_CRATE, RC_GF_MID_NORTH_CENTER_CRATE, - RR_GF_NORTHMOST_CENTER_CRATE, + RC_GF_NORTHMOST_CENTER_CRATE, RC_GF_OUTSKIRTS_NE_CRATE, RC_GF_OUTSKIRTS_NW_CRATE, RC_GF_HBA_RANGE_CRATE_1, From 568639dfc006e15e0d3d3dc4becbadca5aae23d1 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:37:08 -0400 Subject: [PATCH 13/98] skip ItemGet for small keys after skeleton key (#5730) --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bd267aebe..8df83359f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -327,7 +327,10 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { getItemEntry.modIndex == MOD_RANDOMIZER) && (getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK || getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN || - getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) { + getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER || + // Treat small keys as junk if Skeleton Key is obtained. + (getItemEntry.getItemCategory == ITEM_CATEGORY_SMALL_KEY && + Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY))))))) { Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000); } } From ce38e035625e6c0012ea6331c859daae09f6493a Mon Sep 17 00:00:00 2001 From: nclok1405 <155463060+nclok1405@users.noreply.github.com> Date: Wed, 13 Aug 2025 12:38:44 +0900 Subject: [PATCH 14/98] Allow console commands in debug save (#5675) --- .../game-interactor/GameInteractionEffect.cpp | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 03667dd86..76e026206 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -50,7 +50,7 @@ namespace GameInteractionEffect { // MARK: - Flags GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } @@ -62,7 +62,7 @@ void SetSceneFlag::_Apply() { } GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } @@ -74,7 +74,7 @@ void UnsetSceneFlag::_Apply() { } GameInteractionEffectQueryResult SetFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } @@ -86,7 +86,7 @@ void SetFlag::_Apply() { } GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } @@ -99,7 +99,7 @@ void UnsetFlag::_Apply() { // MARK: - ModifyHeartContainers GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ((parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) || (parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))) { @@ -115,7 +115,7 @@ void ModifyHeartContainers::_Apply() { // MARK: - FillMagic GameInteractionEffectQueryResult FillMagic::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) { return GameInteractionEffectQueryResult::NotPossible; @@ -129,7 +129,7 @@ void FillMagic::_Apply() { // MARK: - EmptyMagic GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) { return GameInteractionEffectQueryResult::NotPossible; @@ -143,7 +143,7 @@ void EmptyMagic::_Apply() { // MARK: - ModifyRupees GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) || (parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) { @@ -158,7 +158,7 @@ void ModifyRupees::_Apply() { // MARK: - NoUI GameInteractionEffectQueryResult NoUI::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -173,7 +173,7 @@ void NoUI::_Remove() { // MARK: - ModifyGravity GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -188,7 +188,7 @@ void ModifyGravity::_Remove() { // MARK: - ModifyHealth GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ((parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) || (parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))) { @@ -204,7 +204,7 @@ void ModifyHealth::_Apply() { // MARK: - SetPlayerHealth GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -217,7 +217,7 @@ void SetPlayerHealth::_Apply() { // MARK: - FreezePlayer GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -230,7 +230,7 @@ void FreezePlayer::_Apply() { // MARK: - BurnPlayer GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -243,7 +243,7 @@ void BurnPlayer::_Apply() { // MARK: - ElectrocutePlayer GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -256,7 +256,7 @@ void ElectrocutePlayer::_Apply() { // MARK: - KnockbackPlayer GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || player->stateFlags2 & PLAYER_STATE2_CRAWLING) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { @@ -269,7 +269,7 @@ void KnockbackPlayer::_Apply() { // MARK: - ModifyLinkSize GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -284,7 +284,7 @@ void ModifyLinkSize::_Remove() { // MARK: - InvisibleLink GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -299,7 +299,7 @@ void InvisibleLink::_Remove() { // MARK: - PacifistMode GameInteractionEffectQueryResult PacifistMode::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -314,7 +314,7 @@ void PacifistMode::_Remove() { // MARK: - DisableZTargeting GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -329,7 +329,7 @@ void DisableZTargeting::_Remove() { // MARK: - WeatherRainstorm GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -344,7 +344,7 @@ void WeatherRainstorm::_Remove() { // MARK: - ReverseControls GameInteractionEffectQueryResult ReverseControls::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -359,7 +359,7 @@ void ReverseControls::_Remove() { // MARK: - ForceEquipBoots GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -374,7 +374,7 @@ void ForceEquipBoots::_Remove() { // MARK: - ModifyMovementSpeedMultiplier GameInteractionEffectQueryResult ModifyMovementSpeedMultiplier::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -393,7 +393,7 @@ void ModifyMovementSpeedMultiplier::_Remove() { // MARK: - OneHitKO GameInteractionEffectQueryResult OneHitKO::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -408,7 +408,7 @@ void OneHitKO::_Remove() { // MARK: - ModifyDefenseModifier GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -423,7 +423,7 @@ void ModifyDefenseModifier::_Remove() { // MARK: - GiveOrTakeShield GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & gSaveContext.inventory.equipment)) || @@ -441,7 +441,7 @@ void GiveOrTakeShield::_Apply() { // MARK: - TeleportPlayer GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -453,7 +453,7 @@ void TeleportPlayer::_Apply() { // MARK: - ClearAssignedButtons GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -465,7 +465,7 @@ void ClearAssignedButtons::_Apply() { // MARK: - SetTimeOfDay GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -477,7 +477,7 @@ void SetTimeOfDay::_Apply() { // MARK: - SetCollisionViewer GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -492,7 +492,7 @@ void SetCollisionViewer::_Remove() { // MARK: - RandomizeCosmetics GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -504,7 +504,7 @@ void RandomizeCosmetics::_Apply() { // MARK: - PressButton GameInteractionEffectQueryResult PressButton::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -516,7 +516,7 @@ void PressButton::_Apply() { // MARK: - PressRandomButton GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -528,7 +528,7 @@ void PressRandomButton::_Apply() { // MARK: - AddOrTakeAmmo GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) { return GameInteractionEffectQueryResult::NotPossible; @@ -542,7 +542,7 @@ void AddOrTakeAmmo::_Apply() { // MARK: - RandomBombFuseTimer GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -557,7 +557,7 @@ void RandomBombFuseTimer::_Remove() { // MARK: - DisableLedgeGrabs GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -572,7 +572,7 @@ void DisableLedgeGrabs::_Remove() { // MARK: - RandomWind GameInteractionEffectQueryResult RandomWind::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -587,7 +587,7 @@ void RandomWind::_Remove() { // MARK: - RandomBonks GameInteractionEffectQueryResult RandomBonks::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -602,7 +602,7 @@ void RandomBonks::_Remove() { // MARK: - PlayerInvincibility GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -617,7 +617,7 @@ void PlayerInvincibility::_Remove() { // MARK: - SlipperyFloor GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; @@ -632,7 +632,7 @@ void SlipperyFloor::_Remove() { // MARK: - SpawnEnemyWithOffset GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); @@ -644,7 +644,7 @@ void SpawnEnemyWithOffset::_Apply() { // MARK: - SpawnActor GameInteractionEffectQueryResult SpawnActor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { + if (!GameInteractor::IsSaveLoaded(true)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); From ee20f7f76222cf63f929f8d5f57764266f89ca7e Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 13 Aug 2025 05:39:31 +0200 Subject: [PATCH 15/98] Fix max count for TH keys (#5670) --- .../randomizer/randomizer_item_tracker.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index fcace1017..04bc783d9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -449,7 +449,8 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { result.currentCapacity = IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); result.maxCapacity = - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 : 500; + IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 + : 500; result.currentAmmo = gSaveContext.rupees; break; case ITEM_BOMBCHU: @@ -502,7 +503,28 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; break; case SCENE_THIEVES_HIDEOUT: - result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; + if (IS_RANDO) { + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) { + case RO_GF_CARPENTERS_NORMAL: + result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; + break; + case RO_GF_CARPENTERS_FAST: + result.maxCapacity = 1; + break; + case RO_GF_CARPENTERS_FREE: + result.maxCapacity = 0; + break; + default: + result.maxCapacity = 0; + SPDLOG_ERROR( + "Invalid value for RSK_GERUDO_FORTRESS: " + + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)); + assert(false); + break; + } + } else { + result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; + } break; case SCENE_INSIDE_GANONS_CASTLE: result.maxCapacity = GANONS_CASTLE_SMALL_KEY_MAX; From fadae4997740d6073d6ce01db2950c8a24b3cbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 13 Aug 2025 16:46:36 +0000 Subject: [PATCH 16/98] shipinit bonk damage (#5653) * shipinit bonk damage * no initFunc --- soh/soh/Enhancements/BonkDamage.cpp | 51 +++++++++++++++++++++++++++++ soh/soh/Enhancements/mods.cpp | 44 ------------------------- 2 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 soh/soh/Enhancements/BonkDamage.cpp diff --git a/soh/soh/Enhancements/BonkDamage.cpp b/soh/soh/Enhancements/BonkDamage.cpp new file mode 100644 index 000000000..e11f46b78 --- /dev/null +++ b/soh/soh/Enhancements/BonkDamage.cpp @@ -0,0 +1,51 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "./enhancementTypes.h" + +extern "C" { +#include "functions.h" +#include "macros.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; +} + +void RegisterBonkDamage() { + COND_HOOK(OnPlayerBonk, CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE) != BONK_DAMAGE_NONE, + [] { + uint16_t bonkDamage = 0; + switch (CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE)) { + case BONK_DAMAGE_NONE: + return; + case BONK_DAMAGE_OHKO: + gSaveContext.health = 0; + return; + case BONK_DAMAGE_QUARTER_HEART: + bonkDamage = 4; + break; + case BONK_DAMAGE_HALF_HEART: + bonkDamage = 8; + break; + case BONK_DAMAGE_1_HEART: + bonkDamage = 16; + break; + case BONK_DAMAGE_2_HEARTS: + bonkDamage = 32; + break; + case BONK_DAMAGE_4_HEARTS: + bonkDamage = 64; + break; + case BONK_DAMAGE_8_HEARTS: + bonkDamage = 128; + break; + default: + break; + } + + Health_ChangeBy(gPlayState, -bonkDamage); + // Set invincibility to make Link flash red as a visual damage indicator. + Player* player = GET_PLAYER(gPlayState); + player->invincibilityTimer = 28; + }); +} + +static RegisterShipInitFunc registerBonkDamage(RegisterBonkDamage, { CVAR_ENHANCEMENT("BonkDamageMult") }); diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 5fef9befc..f276e19d3 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -299,49 +299,6 @@ void UpdateHyperEnemiesState() { } } -void RegisterBonkDamage() { - GameInteractor::Instance->RegisterGameHook([]() { - uint8_t bonkOption = CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE); - if (bonkOption == BONK_DAMAGE_NONE) { - return; - } - - if (bonkOption == BONK_DAMAGE_OHKO) { - gSaveContext.health = 0; - return; - } - - uint16_t bonkDamage = 0; - switch (bonkOption) { - case BONK_DAMAGE_QUARTER_HEART: - bonkDamage = 4; - break; - case BONK_DAMAGE_HALF_HEART: - bonkDamage = 8; - break; - case BONK_DAMAGE_1_HEART: - bonkDamage = 16; - break; - case BONK_DAMAGE_2_HEARTS: - bonkDamage = 32; - break; - case BONK_DAMAGE_4_HEARTS: - bonkDamage = 64; - break; - case BONK_DAMAGE_8_HEARTS: - bonkDamage = 128; - break; - default: - break; - } - - Health_ChangeBy(gPlayState, -bonkDamage); - // Set invincibility to make Link flash red as a visual damage indicator. - Player* player = GET_PLAYER(gPlayState); - player->invincibilityTimer = 28; - }); -} - void UpdateDirtPathFixState(int32_t sceneNum) { switch (sceneNum) { case SCENE_HYRULE_FIELD: @@ -982,7 +939,6 @@ void InitMods() { RegisterDeleteFileOnDeath(); RegisterHyperBosses(); UpdateHyperEnemiesState(); - RegisterBonkDamage(); RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); From 7b4df9bdb2ebde2bdd6581c10ffdc1aea4ee1573 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Wed, 13 Aug 2025 21:08:32 +0200 Subject: [PATCH 17/98] Boss Rush cleanup (#5652) * Reduce stuff in the `.h`s & use `COND_HOOK` + variants * Move some boss rush stuff from `z_file_choose.c` * clang * Update BossRush.cpp --- soh/include/z64.h | 2 +- soh/include/z64save.h | 2 +- soh/soh/Enhancements/boss-rush/BossRush.cpp | 339 +++++++++++++++--- soh/soh/Enhancements/boss-rush/BossRush.h | 33 +- .../Enhancements/boss-rush/BossRushTypes.h | 91 ----- .../vanilla-behavior/GIVanillaBehavior.h | 14 + soh/soh/Enhancements/mods.cpp | 2 - soh/src/code/z_parameter.c | 10 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 8 +- .../ovl_file_choose/z_file_choose.c | 162 +-------- 10 files changed, 338 insertions(+), 325 deletions(-) delete mode 100644 soh/soh/Enhancements/boss-rush/BossRushTypes.h diff --git a/soh/include/z64.h b/soh/include/z64.h index 79ecdabcd..70b877f30 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -1522,7 +1522,7 @@ typedef struct { /* 0x34 */ s32 isEnabled; } StickDirectionPrompt; -typedef struct { +typedef struct FileChooseContext { /* 0x00000 */ GameState state; /* 0x000A4 */ Vtx* windowVtx; /* 0x000A8 */ u8* staticSegment; diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 63a9b1d10..bf1342360 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -7,7 +7,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/gameplaystats.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" -#include "soh/Enhancements/boss-rush/BossRushTypes.h" +#include "soh/Enhancements/boss-rush/BossRush.h" typedef enum { /* 0x0 */ MAGIC_STATE_IDLE, // Regular gameplay diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 979f0ad6a..af5c04dd2 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -2,6 +2,8 @@ #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh_assets.h" +#include "soh/frame_interpolation.h" #include #include @@ -14,14 +16,87 @@ extern "C" { #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); +#include "src/overlays/gamestates/ovl_file_choose/file_choose.h" +#include "objects/gameplay_keep/gameplay_keep.h" #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" + +extern PlayState* gPlayState; + +Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); +void FileChoose_UpdateStickDirectionPromptAnim(GameState* thisx); +void FileChoose_DrawTextRec(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t, + f32 dx, f32 dy); } +typedef enum { + BR_CHOICE_BOSSES_ALL, + BR_CHOICE_BOSSES_CHILD, + BR_CHOICE_BOSSES_ADULT, + BR_CHOICE_BOSSES_GANONDORF_GANON +} BossRushBossesChoices; + +typedef enum { + BR_CHOICE_HEARTS_10, + BR_CHOICE_HEARTS_15, + BR_CHOICE_HEARTS_20, + BR_CHOICE_HEARTS_3, + BR_CHOICE_HEARTS_5, + BR_CHOICE_HEARTS_7 +} BossRushHeartsChoices; + +typedef enum { + BR_CHOICE_AMMO_LIMITED, + BR_CHOICE_AMMO_FULL, + BR_CHOICE_AMMO_MAXED, +} BossRushAmmoChoices; + +typedef enum { + BR_CHOICE_HEAL_GANONDORF, + BR_CHOICE_HEAL_EVERYBOSS, + BR_CHOICE_HEAL_NEVER, +} BossRushHealChoices; + +typedef enum { + BR_CHOICE_MAGIC_SINGLE, + BR_CHOICE_MAGIC_DOUBLE, +} BossRushMagicChoices; + +typedef enum { + BR_CHOICE_BGS_NO, + BR_CHOICE_BGS_YES, +} BossRushBgsChoices; + +typedef enum { + BR_CHOICE_BOTTLE_NO, + BR_CHOICE_BOTTLE_EMPTY, + BR_CHOICE_BOTTLE_FAIRY, + BR_CHOICE_BOTTLE_REDPOTION, + BR_CHOICE_BOTTLE_GREENPOTION, + BR_CHOICE_BOTTLE_BLUEPOTION +} BossRushBottleChoices; + +typedef enum { + BR_CHOICE_LONGSHOT_NO, + BR_CHOICE_LONGSHOT_YES, +} BossRushLongshotChoices; + +typedef enum { + BR_CHOICE_HOVERBOOTS_NO, + BR_CHOICE_HOVERBOOTS_YES, +} BossRushHoverBootsChoices; + +typedef enum { + BR_CHOICE_BUNNYHOOD_NO, + BR_CHOICE_BUNNYHOOD_YES, +} BossRushBunnyHoodChoices; + +typedef enum { + BR_CHOICE_TIMER_YES, + BR_CHOICE_TIMER_NO, +} BossRushTimerChoices; + typedef struct BossRushSetting { std::array name; std::vector> choices; @@ -114,6 +189,180 @@ u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) { return static_cast(BossRushOptions[optionIndex].choices.size()); } +void FileChoose_UpdateBossRushMenu(GameState* gameState) { + static s8 sLastBossRushOptionIndex = -1; + static s8 sLastBossRushOptionValue = -1; + + FileChoose_UpdateStickDirectionPromptAnim(gameState); + FileChooseContext* fileChooseContext = (FileChooseContext*)gameState; + Input* input = &fileChooseContext->state.input[0]; + bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0); + + // Fade in elements after opening Boss Rush options menu + fileChooseContext->bossRushUIAlpha += 25; + if (fileChooseContext->bossRushUIAlpha > 255) { + fileChooseContext->bossRushUIAlpha = 255; + } + + // Animate up/down arrows. + fileChooseContext->bossRushArrowOffset += 1; + if (fileChooseContext->bossRushArrowOffset >= 30) { + fileChooseContext->bossRushArrowOffset = 0; + } + + // Move menu selection up or down. + if (ABS(fileChooseContext->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { + // Move down + if (fileChooseContext->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) { + // When selecting past the last option, cycle back to the first option. + if ((fileChooseContext->bossRushIndex + 1) > BR_OPTIONS_MAX - 1) { + fileChooseContext->bossRushIndex = 0; + fileChooseContext->bossRushOffset = 0; + } else { + fileChooseContext->bossRushIndex++; + // When last visible option is selected when moving down, offset the list down by one. + if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset > + BOSSRUSH_MAX_OPTIONS_ON_SCREEN - 1) { + fileChooseContext->bossRushOffset++; + } + } + } else if (fileChooseContext->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 ((fileChooseContext->bossRushIndex - 1) < 0) { + fileChooseContext->bossRushIndex = BR_OPTIONS_MAX - 1; + fileChooseContext->bossRushOffset = + fileChooseContext->bossRushIndex - BOSSRUSH_MAX_OPTIONS_ON_SCREEN + 1; + } else { + // When first visible option is selected when moving up, offset the list up by one. + if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset == 0) { + fileChooseContext->bossRushOffset--; + } + fileChooseContext->bossRushIndex--; + } + } + + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + + // Cycle through choices for currently selected option. + if (ABS(fileChooseContext->stickRelX) > 30 || + (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) { + if (fileChooseContext->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) { + // If exceeding the amount of choices for the selected option, cycle back to the first. + if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] + 1) == + BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex)) { + gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] = 0; + } else { + gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]++; + } + } else if (fileChooseContext->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) { + // If cycling back when already at the first choice for the selected option, cycle back to the last choice. + if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] - 1) < 0) { + gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] = + BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex) - 1; + } else { + gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]--; + } + } + + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + + if (sLastBossRushOptionIndex != fileChooseContext->bossRushIndex || + sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]) { + GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection( + fileChooseContext->bossRushIndex, + gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]); + sLastBossRushOptionIndex = fileChooseContext->bossRushIndex; + sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]; + } + + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + fileChooseContext->configMode = CM_BOSS_RUSH_TO_QUEST; + return; + } + + // Load into the game. + if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + fileChooseContext->buttonIndex = 0xFE; + fileChooseContext->menuMode = FS_MENU_MODE_SELECT; + fileChooseContext->selectMode = SM_FADE_OUT; + fileChooseContext->prevConfigMode = fileChooseContext->configMode; + return; + } +} + +void FileChoose_DrawBossRushMenuWindowContents(FileChooseContext* fileChooseContext) { + OPEN_DISPS(fileChooseContext->state.gfxCtx); + + uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; + uint8_t listOffset = fileChooseContext->bossRushOffset; + uint8_t textAlpha = fileChooseContext->bossRushUIAlpha; + + // Draw arrows to indicate that the list can scroll up or down. + // Arrow up + if (listOffset > 0) { + uint16_t arrowUpX = 140; + uint16_t arrowUpY = 76 - (fileChooseContext->bossRushArrowOffset / 10); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowUpTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + gSPWideTextureRectangle(POLY_OPA_DISP++, arrowUpX << 2, arrowUpY << 2, (arrowUpX + 8) << 2, (arrowUpY + 8) << 2, + G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11)); + } + // Arrow down + if (BR_OPTIONS_MAX - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) { + uint16_t arrowDownX = 140; + uint16_t arrowDownY = 181 + (fileChooseContext->bossRushArrowOffset / 10); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowDownTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + gSPWideTextureRectangle(POLY_OPA_DISP++, arrowDownX << 2, arrowDownY << 2, (arrowDownX + 8) << 2, + (arrowDownY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11)); + } + + // Draw options. There's more options than what fits on the screen, so the visible options + // depend on the current offset of the list. Currently selected option pulses in + // color and has arrows surrounding the option. + for (uint8_t i = listOffset; i - listOffset < BOSSRUSH_MAX_OPTIONS_ON_SCREEN; i++) { + uint16_t textYOffset = (i - listOffset) * 16; + + // Option name. + Interface_DrawTextLine(fileChooseContext->state.gfxCtx, (char*)BossRush_GetSettingName(i, language), 65, + (87 + textYOffset), 255, 255, 80, textAlpha, 0.8f, true); + + // Selected choice for option. + uint16_t finalKerning = Interface_DrawTextLine( + fileChooseContext->state.gfxCtx, + (char*)BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], language), 165, + (87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true); + + // Draw arrows around selected option. + if (fileChooseContext->bossRushIndex == i) { + Gfx_SetupDL_39Opa(fileChooseContext->state.gfxCtx); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickLeftPrompt.arrowColorR, + fileChooseContext->stickLeftPrompt.arrowColorG, + fileChooseContext->stickLeftPrompt.arrowColorB, textAlpha, 160, (92 + textYOffset), + 0.42f, 0, 0, -1.0f, 1.0f); + FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickRightPrompt.arrowColorR, + fileChooseContext->stickRightPrompt.arrowColorG, + fileChooseContext->stickRightPrompt.arrowColorB, textAlpha, (171 + finalKerning), + (92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f); + } + } + + CLOSE_DISPS(fileChooseContext->state.gfxCtx); +} + void BossRush_SpawnBlueWarps(PlayState* play) { // Spawn blue warps in Chamber of Sages based on what bosses have been defeated. @@ -316,7 +565,7 @@ void BossRush_HandleCompleteBoss(PlayState* play) { } } -void BossRush_InitSave() { +extern "C" void BossRush_InitSave() { // Set player name to Lonk for the few textboxes that show up during Boss Rush. Player can't input their own name. std::array brPlayerName = { 21, 50, 49, 46, 62, 62, 62, 62 }; @@ -609,6 +858,17 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li *should = false; break; } + // Handle the heal on blue warp + case VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE: { + if (*should) { + BossRush_HandleBlueWarpHeal(gPlayState); + } + break; + } + case VB_SHOW_GAMEPLAY_TIMER: { + *should |= gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES; + break; + } // Prevent saving case VB_BE_ABLE_TO_SAVE: // Disable doors so the player can't leave the boss rooms backwards. @@ -629,25 +889,6 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li va_end(args); } -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. - if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) { - Actor_Kill(actor); - return; - } -} - 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) { @@ -667,38 +908,32 @@ void BossRush_OnBlueWarpUpdate(void* actor) { } } -void BossRush_RegisterHooks() { - static u32 onVanillaBehaviorHook = 0; - static u32 onSceneInitHook = 0; - static u32 onActorInitHook = 0; - static u32 onBossDefeatHook = 0; - static u32 onActorUpdate = 0; +void RegisterBossRush() { + COND_HOOK(OnLoadGame, true, [](int32_t fileNum) { + COND_ID_HOOK(OnActorInit, ACTOR_DEMO_SA, IS_BOSS_RUSH, [](void* actorPtr) { + BossRush_SpawnBlueWarps(gPlayState); + Actor_Kill((Actor*)actorPtr); + GET_PLAYER(gPlayState)->actor.world.rot.y = 27306; + GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306; + }); - 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); + // Remove bushes, used in Gohma's arena + COND_ID_HOOK(OnActorInit, ACTOR_EN_KUSA, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); }); - onVanillaBehaviorHook = 0; - onSceneInitHook = 0; - onActorInitHook = 0; - onBossDefeatHook = 0; - onActorUpdate = 0; + // Remove pots, used in Barinade's and Ganondorf's arenas + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TSUBO, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); }); - if (!IS_BOSS_RUSH) - return; + // Remove chests, mainly for the chest in King Dodongo's boss room + COND_ID_HOOK(OnActorInit, ACTOR_EN_BOX, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); }); - onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook( - BossRush_OnVanillaBehaviorHandler); - 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); + COND_HOOK(OnVanillaBehavior, IS_BOSS_RUSH, BossRush_OnVanillaBehaviorHandler); + + COND_HOOK(OnSceneInit, IS_BOSS_RUSH, BossRush_OnSceneInitHandler); + + COND_HOOK(OnBossDefeat, IS_BOSS_RUSH, BossRush_OnBossDefeatHandler); + + COND_ID_HOOK(OnActorUpdate, ACTOR_DOOR_WARP1, IS_BOSS_RUSH, BossRush_OnBlueWarpUpdate); }); } + +static RegisterShipInitFunc initFunc(RegisterBossRush); \ 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 881d8d53f..4a47f4f5b 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -1,16 +1,41 @@ #pragma once -#include "z64.h" +#include #ifdef __cplusplus extern "C" { #endif -void BossRush_HandleBlueWarpHeal(PlayState* play); -void BossRush_InitSave(); +struct GameState; +struct FileChooseContext; + +void FileChoose_UpdateBossRushMenu(struct GameState* gameState); +void FileChoose_DrawBossRushMenuWindowContents(struct FileChooseContext* fileChooseContext); 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 + +#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6 + +typedef enum { + BR_OPTIONS_BOSSES, + BR_OPTIONS_HEARTS, + BR_OPTIONS_AMMO, + BR_OPTIONS_HEAL, + BR_OPTIONS_HYPERBOSSES, + BR_OPTIONS_MAGIC, + BR_OPTIONS_BGS, + BR_OPTIONS_BOTTLE, + BR_OPTIONS_LONGSHOT, + BR_OPTIONS_HOVERBOOTS, + BR_OPTIONS_BUNNYHOOD, + BR_OPTIONS_TIMER, + BR_OPTIONS_MAX, +} BossRushOptionEnums; + +typedef enum { + BR_CHOICE_HYPERBOSSES_NO, + BR_CHOICE_HYPERBOSSES_YES, +} BossRushHyperBossesChoices; \ No newline at end of file diff --git a/soh/soh/Enhancements/boss-rush/BossRushTypes.h b/soh/soh/Enhancements/boss-rush/BossRushTypes.h deleted file mode 100644 index 973f1599f..000000000 --- a/soh/soh/Enhancements/boss-rush/BossRushTypes.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6 - -typedef enum { - BR_OPTIONS_BOSSES, - BR_OPTIONS_HEARTS, - BR_OPTIONS_AMMO, - BR_OPTIONS_HEAL, - BR_OPTIONS_HYPERBOSSES, - BR_OPTIONS_MAGIC, - BR_OPTIONS_BGS, - BR_OPTIONS_BOTTLE, - BR_OPTIONS_LONGSHOT, - BR_OPTIONS_HOVERBOOTS, - BR_OPTIONS_BUNNYHOOD, - BR_OPTIONS_TIMER, - BR_OPTIONS_MAX, -} BossRushOptionEnums; - -typedef enum { - BR_CHOICE_BOSSES_ALL, - BR_CHOICE_BOSSES_CHILD, - BR_CHOICE_BOSSES_ADULT, - BR_CHOICE_BOSSES_GANONDORF_GANON -} BossRushBossesChoices; - -typedef enum { - BR_CHOICE_HEARTS_10, - BR_CHOICE_HEARTS_15, - BR_CHOICE_HEARTS_20, - BR_CHOICE_HEARTS_3, - BR_CHOICE_HEARTS_5, - BR_CHOICE_HEARTS_7 -} BossRushHeartsChoices; - -typedef enum { - BR_CHOICE_AMMO_LIMITED, - BR_CHOICE_AMMO_FULL, - BR_CHOICE_AMMO_MAXED, -} BossRushAmmoChoices; - -typedef enum { - BR_CHOICE_HEAL_GANONDORF, - BR_CHOICE_HEAL_EVERYBOSS, - BR_CHOICE_HEAL_NEVER, -} BossRushHealChoices; - -typedef enum { - BR_CHOICE_HYPERBOSSES_NO, - BR_CHOICE_HYPERBOSSES_YES, -} BossRushHyperBossesChoices; - -typedef enum { - BR_CHOICE_MAGIC_SINGLE, - BR_CHOICE_MAGIC_DOUBLE, -} BossRushMagicChoices; - -typedef enum { - BR_CHOICE_BGS_NO, - BR_CHOICE_BGS_YES, -} BossRushBgsChoices; - -typedef enum { - BR_CHOICE_BOTTLE_NO, - BR_CHOICE_BOTTLE_EMPTY, - BR_CHOICE_BOTTLE_FAIRY, - BR_CHOICE_BOTTLE_REDPOTION, - BR_CHOICE_BOTTLE_GREENPOTION, - BR_CHOICE_BOTTLE_BLUEPOTION -} BossRushBottleChoices; - -typedef enum { - BR_CHOICE_LONGSHOT_NO, - BR_CHOICE_LONGSHOT_YES, -} BossRushLongshotChoices; - -typedef enum { - BR_CHOICE_HOVERBOOTS_NO, - BR_CHOICE_HOVERBOOTS_YES, -} BossRushHoverBootsChoices; - -typedef enum { - BR_CHOICE_BUNNYHOOD_NO, - BR_CHOICE_BUNNYHOOD_YES, -} BossRushBunnyHoodChoices; - -typedef enum { - BR_CHOICE_TIMER_YES, - BR_CHOICE_TIMER_NO, -} BossRushTimerChoices; diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 0ba910cf6..09defd088 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2225,6 +2225,20 @@ typedef enum { // #### `result` // ```c + // DoorWarp1_PlayerInRange(this, play) + // ``` + // #### `args` + // - `*DoorWarp1` + VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE, + + // #### `result` + // ```c + // (CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum + // <= 2) + // ``` + // #### `args` + // - `*PlayState` + VB_SHOW_GAMEPLAY_TIMER, // (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && // this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100 // ``` diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index f276e19d3..2f56cadd6 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -6,7 +6,6 @@ #include "soh/SaveManager.h" #include "soh/ResourceManagerHelpers.h" #include "soh/resource/type/Skeleton.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" @@ -930,7 +929,6 @@ void RegisterCustomSkeletons() { } void InitMods() { - BossRush_RegisterHooks(); RandomizerRegisterHooks(); TimeSaverRegisterHooks(); RegisterTTS(); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 0fc923070..f2713c8d6 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -8,7 +8,6 @@ #include "libultraship/bridge.h" #include "soh/Enhancements/gameplaystats.h" -#include "soh/Enhancements/boss-rush/BossRushTypes.h" #include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/enhancementTypes.h" @@ -6374,11 +6373,10 @@ void Interface_Draw(PlayState* play) { void Interface_DrawTotalGameplayTimer(PlayState* play) { // Draw timer based on the Gameplay Stats total time. - - if ((IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES) || - (CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && - gSaveContext.fileNum <= 2)) { - + if (GameInteractor_Should(VB_SHOW_GAMEPLAY_TIMER, + CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && + gSaveContext.fileNum <= 2, + play)) { s32 X_Margins_Timer = 0; if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.UseMargins"), 0) != 0) { if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.PosType"), 0) == ORIGINAL_LOCATION) { 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 54e9768b4..2e0cd458f 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 @@ -1,7 +1,6 @@ #include "z_door_warp1.h" #include "objects/object_warp1/object_warp1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" -#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -693,12 +692,7 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); - if (DoorWarp1_PlayerInRange(this, play)) { - // Heal player in Boss Rush - if (IS_BOSS_RUSH) { - BossRush_HandleBlueWarpHeal(play); - } - + if (GameInteractor_Should(VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE, DoorWarp1_PlayerInRange(this, play), this)) { player = GET_PLAYER(play); OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM); 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 8fa504748..9e58f5e31 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 @@ -1398,110 +1398,6 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { } } -static s8 sLastBossRushOptionIndex = -1; -static s8 sLastBossRushOptionValue = -1; - -void FileChoose_UpdateBossRushMenu(GameState* thisx) { - FileChoose_UpdateStickDirectionPromptAnim(thisx); - FileChooseContext* this = (FileChooseContext*)thisx; - Input* input = &this->state.input[0]; - bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0); - - // Fade in elements after opening Boss Rush options menu - this->bossRushUIAlpha += 25; - if (this->bossRushUIAlpha > 255) { - this->bossRushUIAlpha = 255; - } - - // Animate up/down arrows. - this->bossRushArrowOffset += 1; - if (this->bossRushArrowOffset >= 30) { - this->bossRushArrowOffset = 0; - } - - // Move menu selection up or down. - if (ABS(this->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - // 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) > BR_OPTIONS_MAX - 1) { - this->bossRushIndex = 0; - this->bossRushOffset = 0; - } else { - this->bossRushIndex++; - // When last visible option is selected when moving down, offset the list down by one. - if (this->bossRushIndex - this->bossRushOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN - 1) { - this->bossRushOffset++; - } - } - } 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 = 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. - if (this->bossRushIndex - this->bossRushOffset == 0) { - this->bossRushOffset--; - } - this->bossRushIndex--; - } - } - - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } - - // Cycle through choices for currently selected option. - if (ABS(this->stickRelX) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) { - if (this->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) { - // If exceeding the amount of choices for the selected option, cycle back to the first. - if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] + 1) == - BossRush_GetSettingOptionsAmount(this->bossRushIndex)) { - gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] = 0; - } else { - gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]++; - } - } else if (this->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) { - // If cycling back when already at the first choice for the selected option, cycle back to the last choice. - if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] - 1) < 0) { - gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] = - BossRush_GetSettingOptionsAmount(this->bossRushIndex) - 1; - } else { - gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]--; - } - } - - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } - - if (sLastBossRushOptionIndex != this->bossRushIndex || - sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]) { - GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection( - this->bossRushIndex, gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]); - sLastBossRushOptionIndex = this->bossRushIndex; - sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]; - } - - if (CHECK_BTN_ALL(input->press.button, BTN_B)) { - this->configMode = CM_BOSS_RUSH_TO_QUEST; - return; - } - - // Load into the game. - if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->buttonIndex = 0xFE; - this->menuMode = FS_MENU_MODE_SELECT; - this->selectMode = SM_FADE_OUT; - this->prevConfigMode = this->configMode; - return; - } -} - void FileChoose_UpdateRandomizerMenu(GameState* thisx) { FileChoose_UpdateStickDirectionPromptAnim(thisx); FileChooseContext* this = (FileChooseContext*)thisx; @@ -2590,63 +2486,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { break; } } else if (this->configMode == CM_BOSS_RUSH_MENU) { - uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; - uint8_t listOffset = this->bossRushOffset; - uint8_t textAlpha = this->bossRushUIAlpha; - - // Draw arrows to indicate that the list can scroll up or down. - // Arrow up - if (listOffset > 0) { - uint16_t arrowUpX = 140; - uint16_t arrowUpY = 76 - (this->bossRushArrowOffset / 10); - gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowUpTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOLOD); - gSPWideTextureRectangle(POLY_OPA_DISP++, arrowUpX << 2, arrowUpY << 2, (arrowUpX + 8) << 2, - (arrowUpY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11)); - } - // Arrow down - 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, G_IM_SIZ_16b, 16, 16, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOLOD); - gSPWideTextureRectangle(POLY_OPA_DISP++, arrowDownX << 2, arrowDownY << 2, (arrowDownX + 8) << 2, - (arrowDownY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11)); - } - - // Draw options. There's more options than what fits on the screen, so the visible options - // depend on the current offset of the list. Currently selected option pulses in - // color and has arrows surrounding the option. - for (uint8_t i = listOffset; i - listOffset < BOSSRUSH_MAX_OPTIONS_ON_SCREEN; i++) { - uint16_t textYOffset = (i - listOffset) * 16; - - // Option name. - Interface_DrawTextLine(this->state.gfxCtx, BossRush_GetSettingName(i, language), 65, (87 + textYOffset), - 255, 255, 80, textAlpha, 0.8f, true); - - // Selected choice for option. - uint16_t finalKerning = Interface_DrawTextLine( - this->state.gfxCtx, - BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], language), 165, - (87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true); - - // Draw arrows around selected option. - if (this->bossRushIndex == i) { - Gfx_SetupDL_39Opa(this->state.gfxCtx); - gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOLOD); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR, - this->stickLeftPrompt.arrowColorG, this->stickLeftPrompt.arrowColorB, textAlpha, - 160, (92 + textYOffset), 0.42f, 0, 0, -1.0f, 1.0f); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR, - this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, - textAlpha, (171 + finalKerning), (92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f); - } - } + FileChoose_DrawBossRushMenuWindowContents(this); } else if (this->configMode == CM_RANDOMIZER_SETTINGS_MENU) { uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; uint8_t textAlpha = this->randomizerUIAlpha; From 9ff9bebaa297a2d5afa5e58315fd4bb667ffbaf3 Mon Sep 17 00:00:00 2001 From: Jordan Longstaff Date: Mon, 25 Aug 2025 14:59:28 -0400 Subject: [PATCH 18/98] Fix faulty Nocturne trigger when receiving Fire Medallion (#5761) --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 2 +- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 8df83359f..babea1c50 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -868,7 +868,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT && gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER); + CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && gSaveContext.cutsceneIndex < 0xFFF0; break; case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: { // Don't require a bomb bag to get prize in rando diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index b847fca51..27bf1f02d 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -165,7 +165,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li *should = false; } - u8 meetsBurningKakRequirements = LINK_IS_ADULT && + u8 meetsBurningKakRequirements = LINK_IS_ADULT && gSaveContext.cutsceneIndex < 0xFFF0 && gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && From b6166f41c85c5834a4e68807bb94d3460f7033d1 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 25 Aug 2025 11:59:38 -0700 Subject: [PATCH 19/98] Restore previous state of `z_door_warp1.c`, and reimplement boss rush blue warp bypass. This also fixes the issue with shadow and spirit medallions not being given in vanilla without cutscene skips on. (#5763) Ensure shadow and spirit medallions get queued when skipping story cutscenes in vanilla. --- .../TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp | 9 +++++++++ soh/soh/Enhancements/boss-rush/BossRush.cpp | 4 ++++ soh/soh/Enhancements/timesaver_hook_handlers.cpp | 5 ++++- soh/soh/Enhancements/timesaver_hook_handlers.h | 3 +++ soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c | 6 ++---- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index 674adcdfb..de2e5fc5f 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/timesaver_hook_handlers.h" extern "C" { #include "macros.h" @@ -12,6 +13,7 @@ extern "C" { #define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() +extern "C" PlayState* gPlayState; static bool sEnteredBlueWarp = false; /** @@ -124,6 +126,13 @@ void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_lis */ void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + if (IS_VANILLA) { + if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { + TimeSaverQueueItem(RG_SHADOW_MEDALLION); + } else if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { + TimeSaverQueueItem(RG_SPIRIT_MEDALLION); + } + } *should = false; } } diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 76cf5637e..17ffd70c7 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -501,6 +501,10 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } + case VB_PLAY_BLUE_WARP_CS: { + *should = false; + break; + } // Spawn clean blue warps (no ruto, adult animation, etc) case VB_SPAWN_BLUE_WARP: { switch (gPlayState->sceneNum) { diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 27bf1f02d..fdcc23ba3 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -1,6 +1,5 @@ #include #include "soh/OTRGlobals.h" -#include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/enhancementTypes.h" @@ -1199,6 +1198,10 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) { static GetItemEntry vanillaQueuedItemEntry = GET_ITEM_NONE; +void TimeSaverQueueItem(RandomizerGet randoGet) { + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(randoGet).GetGIEntry_Copy(); +} + void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { // Do nothing when in a boss rush if (IS_BOSS_RUSH) { diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.h b/soh/soh/Enhancements/timesaver_hook_handlers.h index 41bccd8d9..373c9eaf8 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.h +++ b/soh/soh/Enhancements/timesaver_hook_handlers.h @@ -1,6 +1,9 @@ #ifndef TIMESAVER_HOOK_HANDLERS_H #define TIMESAVER_HOOK_HANDLERS_H +#include "soh/Enhancements/randomizer/randomizerTypes.h" + void TimeSaverRegisterHooks(); +void TimeSaverQueueItem(RandomizerGet randoGet); #endif // TIMESAVER_HOOK_HANDLERS_H \ No newline at end of file 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 54e9768b4..a90764717 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 @@ -813,8 +813,7 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { - if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, - !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), + if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) { @@ -832,8 +831,7 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { - if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, - !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), + if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) { Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) { From 224efe2946d5903a69855188b0bcba268b03638e Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Mon, 25 Aug 2025 19:59:47 +0100 Subject: [PATCH 20/98] Fix TOT_MASTER_SWORD when the master sword is stated with but not shuffled. (#5705) * Fix TOT_MASTER_SWORD when the master sword is stated with but not shuffled. * remove RC_MASTER_SWORD_PEDESTAL --- soh/soh/Enhancements/randomizer/context.cpp | 2 +- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 -- soh/soh/Enhancements/randomizer/settings.cpp | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 243f22ea6..d291655a0 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -170,7 +170,7 @@ void Context::GenerateLocationPool() { // TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.) if (location.GetRandomizerCheck() == RC_UNKNOWN_CHECK || location.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || // already in pool - (location.GetRandomizerCheck() == RC_MASTER_SWORD_PEDESTAL && + (location.GetRandomizerCheck() == RC_TOT_MASTER_SWORD && mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) || (location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD && mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) || diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index babea1c50..9e77d27c4 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -884,7 +884,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_GIVE_ITEM_MASTER_SWORD: - if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD)) { + if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD) || RAND_GET_OPTION(RSK_STARTING_MASTER_SWORD)) { *should = false; } else { *should = true; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index d9eae0af8..63dbeb389 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2609,7 +2609,6 @@ typedef enum { RC_PIERRE, RC_DELIVER_RUTOS_LETTER, - RC_MASTER_SWORD_PEDESTAL, RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RC_KF_GOSSIP_STONE, @@ -4902,7 +4901,6 @@ typedef enum { RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RHT_GANONS_TOWER_BOSS_KEY_CHEST, RHT_DELIVER_RUTOS_LETTER, - RHT_MASTER_SWORD_PEDESTAL, // Beehives RHT_BEEHIVE_CHEST_GROTTO, RHT_BEEHIVE_COW_GROTTO, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index a9f7b4e64..d2f93fe98 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -2571,7 +2571,7 @@ void Context::FinalizeSettings(const std::set& excludedLocation } if (!mOptions[RSK_SHUFFLE_MASTER_SWORD]) { if (mOptions[RSK_STARTING_MASTER_SWORD]) { - this->GetItemLocation(RC_MASTER_SWORD_PEDESTAL)->SetExcludedOption(1); + this->GetItemLocation(RC_TOT_MASTER_SWORD)->SetExcludedOption(1); } } if (!mOptions[RSK_SHUFFLE_OCARINA]) { From 820d097c84efccdbd30fa633df74a422200d5e53 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Mon, 25 Aug 2025 15:00:04 -0400 Subject: [PATCH 21/98] Fix King Dodongo door switch cutscene (#5729) * fix parathenses to properly OR * clang clang clang --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index fdcc23ba3..4af24ad19 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -300,9 +300,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } switch (actor->id) { case ACTOR_OBJ_SWITCH: { - if ((actor->params == 8224 && gPlayState->sceneNum == SCENE_DODONGOS_CAVERN) || - (actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) && - CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { + if (((actor->params == 8224 && gPlayState->sceneNum == SCENE_DODONGOS_CAVERN) || + (actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE)) && + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { break; } ObjSwitch* switchActor = (ObjSwitch*)actor; From 21e37d9ac2ad14996d7d50585f3ea1682a7467b4 Mon Sep 17 00:00:00 2001 From: balloondude2 <55861555+balloondude2@users.noreply.github.com> Date: Mon, 25 Aug 2025 13:00:28 -0600 Subject: [PATCH 22/98] Fix the Show Horizontal Resolution Field option v2 (#5744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move showHorizontalResField initialization * remove redundant assignment Co-authored-by: Philip Dubé --------- Co-authored-by: Philip Dubé --- soh/soh/SohGui/ResolutionEditor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/SohGui/ResolutionEditor.cpp b/soh/soh/SohGui/ResolutionEditor.cpp index d33a7b43c..d3810f6a4 100644 --- a/soh/soh/SohGui/ResolutionEditor.cpp +++ b/soh/soh/SohGui/ResolutionEditor.cpp @@ -563,7 +563,6 @@ void UpdateResolutionVars() { verticalPixelCount = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", pixelCountPresets[item_pixelCount]); // Additional settings - showHorizontalResField = false; horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; // Disabling flags disabled_everything = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); From 9eafa852b5a539ce505600294ad2edeaa053ca05 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 25 Aug 2025 21:00:59 +0200 Subject: [PATCH 23/98] Fix Dampe Going Backwards (#5731) * Add FixDampeGoingBackwards * Update SohMenuEnhancements.cpp --- soh/assets/custom/presets/Main Enhanced.json | 1 + soh/assets/custom/presets/Main Randomizer.json | 1 + soh/assets/custom/presets/Main Vanilla+.json | 1 + soh/soh/SohGui/SohMenuEnhancements.cpp | 4 ++++ soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c | 5 +++++ 5 files changed, 12 insertions(+) diff --git a/soh/assets/custom/presets/Main Enhanced.json b/soh/assets/custom/presets/Main Enhanced.json index 5e63d651f..eabda809f 100644 --- a/soh/assets/custom/presets/Main Enhanced.json +++ b/soh/assets/custom/presets/Main Enhanced.json @@ -16,6 +16,7 @@ "EnemySpawnsOverWaterboxes": 1, "FasterRupeeAccumulator": 1, "FixBrokenGiantsKnife": 1, + "FixDampeGoingBackwards": 1, "FixDaruniaDanceSpeed": 1, "FixDungeonMinimapIcon": 1, "FixEyesOpenWhileSleeping": 1, diff --git a/soh/assets/custom/presets/Main Randomizer.json b/soh/assets/custom/presets/Main Randomizer.json index 7ece7315a..2982a8b72 100644 --- a/soh/assets/custom/presets/Main Randomizer.json +++ b/soh/assets/custom/presets/Main Randomizer.json @@ -45,6 +45,7 @@ "FishNeverEscape": 1, "FixBrokenGiantsKnife": 1, "FixDaruniaDanceSpeed": 1, + "FixDampeGoingBackwards": 1, "FixDungeonMinimapIcon": 1, "FixFloorSwitches": 1, "FixHammerHand": 1, diff --git a/soh/assets/custom/presets/Main Vanilla+.json b/soh/assets/custom/presets/Main Vanilla+.json index 0f6c1741a..1ac97a567 100644 --- a/soh/assets/custom/presets/Main Vanilla+.json +++ b/soh/assets/custom/presets/Main Vanilla+.json @@ -17,6 +17,7 @@ "FasterRupeeAccumulator": 1, "FixBrokenGiantsKnife": 1, "FixDaruniaDanceSpeed": 1, + "FixDampeGoingBackwards": 1, "FixDungeonMinimapIcon": 1, "FixEyesOpenWhileSleeping": 1, "FixFloorSwitches": 1, diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 488aeb720..2a40cb23c 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -942,6 +942,10 @@ void SohMenu::AddMenuEnhancements() { }) .Options(CheckboxOptions().Tooltip( "Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads.")); + AddWidget(path, "Fix Dampé Going Backwards", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("FixDampeGoingBackwards")) + .Options(CheckboxOptions().Tooltip( + "Fixes Dampé going backwards in certain circumstances when the player is going backwards.")); AddWidget(path, "Fix Raised Floor Switches", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("FixFloorSwitches")) .Options(CheckboxOptions().Tooltip( diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c index d850021a4..c62db2dd8 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c +++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c @@ -238,6 +238,11 @@ void EnPoRelay_Race(EnPoRelay* this, PlayState* play) { } else { speed = 3.5f; } + + if (CVarGetInteger(CVAR_ENHANCEMENT("FixDampeGoingBackwards"), false)) { + speed = ABS(speed); + } + multiplier = 250.0f - this->actor.xzDistToPlayer; multiplier = CLAMP_MIN(multiplier, 0.0f); speed += multiplier * 0.02f + 1.0f; From 3128fb0112b94784f1dc433c1814fb00f4d8e0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Aug 2025 19:01:17 +0000 Subject: [PATCH 24/98] Fix crash on selling big poe (#5733) * Fix crash on selling big poe Easiest steps to reproduce: set poe's to 0, put big poe in inventory, trigger text using big poe bottle I overlooked selling poes with using bottle instead of talking to collector * disable hint when count zero --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 3 ++- soh/soh/Enhancements/randomizer/settings.cpp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 447125ae1..bf2722f80 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1091,7 +1091,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_SELL_POES_TO_POE_COLLECTOR: { - if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES) && HIGH_SCORE(HS_POE_POINTS) >= 1000) { + if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES) && HIGH_SCORE(HS_POE_POINTS) >= 1000 && + !(GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS)) { EnGb* enGb = va_arg(args, EnGb*); enGb->textId = 0x70F8; Message_ContinueTextbox(gPlayState, enGb->textId); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..d94905ae1 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -2515,10 +2515,10 @@ void Settings::UpdateOptionProperties() { "setting where you present the loach to the fishing pond owner."); } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 7) == 0) { - mOptions[RSK_CHICKENS_HINT].Disable("Anju will just give you the item instead with 0 chickens."); + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 10) == 0) { + mOptions[RSK_BIG_POES_HINT].Disable("Poe Collector will just give you the item instead with 0 big poes."); } else { - mOptions[RSK_CHICKENS_HINT].Enable(); + mOptions[RSK_BIG_POES_HINT].Enable(); } } From 4a9a98d93c4844298725125cfaa7fbd7e10ec008 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 25 Aug 2025 14:01:25 -0500 Subject: [PATCH 25/98] SDL_GameControllerDB repo owner gabomdq -> mdqinc (#5740) * SDL_GameControllerDB repo owner gabomdq -> mdqinc gabomdq redirects to mdqinc * Docs SDL_GameControllerDB repo owner gabomdq -> mdqinc --- docs/GAME_CONTROLLER_DB.md | 60 +++++++++++++++++++------------------- soh/CMakeLists.txt | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/GAME_CONTROLLER_DB.md b/docs/GAME_CONTROLLER_DB.md index 3867f5a63..fe8c9285c 100644 --- a/docs/GAME_CONTROLLER_DB.md +++ b/docs/GAME_CONTROLLER_DB.md @@ -1,38 +1,38 @@ # SDL GameControllerDB The Ship of Harkinian utilizes a text file with SDL controller mappings for extended controller hardware support. -This file is pulled from https://github.com/gabomdq/SDL_GameControllerDB during the build process as [a part of CMakeLists.txt](https://github.com/HarbourMasters/Shipwright/blob/bb643661f62865dfc757c185d0daaebb32f2d53d/soh/CMakeLists.txt#L760). +This file is pulled from https://github.com/mdqinc/SDL_GameControllerDB during the build process as [a part of CMakeLists.txt](https://github.com/HarbourMasters/Shipwright/blob/bb643661f62865dfc757c185d0daaebb32f2d53d/soh/CMakeLists.txt#L760). ## Released versions | Release | sha | diff | | - | - | - | -| Zhora Alfa 4.0.0 | [967daa8](https://github.com/gabomdq/SDL_GameControllerDB/tree/967daa8f89c48b01ed0f9c6a86ac849930442fc6) | | -| Zhora Bravo 4.0.1 | [ccac7cd](https://github.com/gabomdq/SDL_GameControllerDB/tree/ccac7cd97f445955d4437e21c5f82123d9b4349b) | [+1](https://github.com/gabomdq/SDL_GameControllerDB/compare/967daa8...ccac7cd) | -| Zhora Charlie 4.0.2 | [ff26eb0](https://github.com/gabomdq/SDL_GameControllerDB/tree/ff26eb04d0fe18356985d968119429d6012e7d75) | [+8/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/ccac7cd...ff26eb0) | -| Zhora Delta 4.0.3 | [ad02da5](https://github.com/gabomdq/SDL_GameControllerDB/tree/ad02da5a95ca8005f2c1facc11a5a52f8522f0ee) | [+4/-5](https://github.com/gabomdq/SDL_GameControllerDB/compare/ff26eb0...ad02da5) | -| Zohra Echo 4.0.4 | [c203690](https://github.com/gabomdq/SDL_GameControllerDB/tree/c203690b1e13980699802918d362cd9dadf89bd0) | [+8/-4](https://github.com/gabomdq/SDL_GameControllerDB/compare/ad02da5...c203690) | -| Zhora Foxtrot 4.0.5 | [9db8101](https://github.com/gabomdq/SDL_GameControllerDB/tree/9db8101a5780d1b0721bf6de385e6ffe0d07dfc7) | [+6](https://github.com/gabomdq/SDL_GameControllerDB/compare/c203690...9db8101) | -| Flynn Alfa 5.0.0 | [163cc5d](https://github.com/gabomdq/SDL_GameControllerDB/tree/163cc5d45e9fc2f1bb2b95ea7eee4bbc9a57955c) | [+29/-8](https://github.com/gabomdq/SDL_GameControllerDB/compare/9db8101...163cc5d) | -| Flynn Bravo 5.0.1 | [7efce7d](https://github.com/gabomdq/SDL_GameControllerDB/tree/7efce7d3f309ec1fa409b1af09153f9eb77fbedf) | [-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/163cc5d...7efce7d) | -| Flynn Charlie 5.0.2 | [e607703](https://github.com/gabomdq/SDL_GameControllerDB/tree/e607703392145343e8aca42be052121c0b7bd1c9) | [+40/-17](https://github.com/gabomdq/SDL_GameControllerDB/compare/7efce7d...e607703) | -| Bradley Alfa 5.1.0 | [2ba9676](https://github.com/gabomdq/SDL_GameControllerDB/tree/2ba96761af795c15e916cc97790b51e09dc0cd54) | [+1/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/e607703...2ba9676) | -| Bradley Charlie 5.1.2 | [4f5d1d4](https://github.com/gabomdq/SDL_GameControllerDB/tree/4f5d1d497985b75f4a83a5de46f596dc4d7f002e) | [+5/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/2ba9676...4f5d1d4) | -| Bradley Delta 5.1.3 | [9b73049](https://github.com/gabomdq/SDL_GameControllerDB/tree/9b73049ee62a2cc862d6ad94c2c777f2e8363a48) | [+4/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/4f5d1d4...9b73049) | -| Bradley Echo 5.1.4 | [6d3801f](https://github.com/gabomdq/SDL_GameControllerDB/tree/6d3801fcfe74b1989de96403b7b560eba72a175c) | [+56/-21](https://github.com/gabomdq/SDL_GameControllerDB/compare/9b73049...6d3801f) | -| Gibbs Alfa 6.0.0 | [0562b00](https://github.com/gabomdq/SDL_GameControllerDB/tree/0562b00eaf5c0308c49d329b79263d2dae1c3a85) | [+8/-2](https://github.com/gabomdq/SDL_GameControllerDB/compare/6d3801f...0562b00) | -| Khan Alfa 6.1.0 | [436c7e3](https://github.com/gabomdq/SDL_GameControllerDB/tree/436c7e3d54a57189ea0ab44d05f36b7cc7ea496c) | [+31/-16](https://github.com/gabomdq/SDL_GameControllerDB/compare/0562b00...436c7e3) | -| Khan Bravo 6.1.1 | [01cca2e](https://github.com/gabomdq/SDL_GameControllerDB/tree/01cca2e77f9bf9f1432be04f876f287eb78297fe) | [+23/-6](https://github.com/gabomdq/SDL_GameControllerDB/compare/436c7e3...01cca2e) | -| Khan Charlie 6.1.2 | [6852946](https://github.com/gabomdq/SDL_GameControllerDB/tree/6852946487534c69b7d228fd4eb8c87cf6966475) | [+25/-15](https://github.com/gabomdq/SDL_GameControllerDB/compare/01cca2e...6852946) | -| Spock Alfa 7.0.0 | [38bda81](https://github.com/gabomdq/SDL_GameControllerDB/tree/38bda816dc786f18493876f7bc30bc12dfd2636a) | [+15/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/6852946...38bda81) | -| Spock Bravo 7.0.1 | [228d980](https://github.com/gabomdq/SDL_GameControllerDB/tree/228d980d3d791e9df3b096472f6b97459f8709fe) | [+7/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/38bda81...228d980) | -| Spock Charlie 7.0.2 | [c5b4df0](https://github.com/gabomdq/SDL_GameControllerDB/tree/c5b4df0e1061175cb11e3ebbf8045178339864a5) | [+3](https://github.com/gabomdq/SDL_GameControllerDB/compare/228d980...c5b4df0) | -| Sulu Alfa 7.1.0 | [a2cf171](https://github.com/gabomdq/SDL_GameControllerDB/tree/a2cf1711b4ebc646a3814705d2fb6aac5707bcae) | [+4/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/c5b4df0...a2cf171) | -| Sulu Bravo 7.1.1 | [cc9f777](https://github.com/gabomdq/SDL_GameControllerDB/tree/cc9f777721f0cb30058d9eef52a295130b734a4a) | [+29/-9](https://github.com/gabomdq/SDL_GameControllerDB/compare/a2cf171...cc9f777) | -| MacReady Alfa 8.0.0 | [c56329f](https://github.com/gabomdq/SDL_GameControllerDB/tree/c56329f4df93fc7a780bdbeae47a9c91447b629c) | [+67/-23](https://github.com/gabomdq/SDL_GameControllerDB/compare/cc9f777...c56329f) | -| MacReady Bravo 8.0.1 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+5/-5](https://github.com/gabomdq/SDL_GameControllerDB/compare/c56329f...721b575) | -| MacReady Charlie 8.0.2 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+0/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...721b575) | -| MacReady Delta 8.0.3 | [d4ab609](https://github.com/gabomdq/SDL_GameControllerDB/tree/d4ab609121ee6e687bc3d3a7e80244b3b26d1164) | [+5/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...d4ab609) | -| MacReady Echo 8.0.4 | [6555d47](https://github.com/gabomdq/SDL_GameControllerDB/tree/6555d47ecb5d9eebac0e3d8cd19a545e9d946c40) | [+2/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/d4ab609...6555d47) | -| MacReady Foxtrot 8.0.5 | [037d6a1](https://github.com/gabomdq/SDL_GameControllerDB/tree/037d6a1533ed94fbc6a8c71e6f1f9aff1e46208a) | [+47/-14](https://github.com/gabomdq/SDL_GameControllerDB/compare/6555d47...037d6a1) | -| MacReady Golf 8.0.6 | [075c154](https://github.com/gabomdq/SDL_GameControllerDB/tree/075c1549075ef89a397fd7e0663d21e53a2485fd) | [+340/-301](https://github.com/gabomdq/SDL_GameControllerDB/compare/037d6a1...075c154) | +| Zhora Alfa 4.0.0 | [967daa8](https://github.com/mdqinc/SDL_GameControllerDB/tree/967daa8f89c48b01ed0f9c6a86ac849930442fc6) | | +| Zhora Bravo 4.0.1 | [ccac7cd](https://github.com/mdqinc/SDL_GameControllerDB/tree/ccac7cd97f445955d4437e21c5f82123d9b4349b) | [+1](https://github.com/mdqinc/SDL_GameControllerDB/compare/967daa8...ccac7cd) | +| Zhora Charlie 4.0.2 | [ff26eb0](https://github.com/mdqinc/SDL_GameControllerDB/tree/ff26eb04d0fe18356985d968119429d6012e7d75) | [+8/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/ccac7cd...ff26eb0) | +| Zhora Delta 4.0.3 | [ad02da5](https://github.com/mdqinc/SDL_GameControllerDB/tree/ad02da5a95ca8005f2c1facc11a5a52f8522f0ee) | [+4/-5](https://github.com/mdqinc/SDL_GameControllerDB/compare/ff26eb0...ad02da5) | +| Zohra Echo 4.0.4 | [c203690](https://github.com/mdqinc/SDL_GameControllerDB/tree/c203690b1e13980699802918d362cd9dadf89bd0) | [+8/-4](https://github.com/mdqinc/SDL_GameControllerDB/compare/ad02da5...c203690) | +| Zhora Foxtrot 4.0.5 | [9db8101](https://github.com/mdqinc/SDL_GameControllerDB/tree/9db8101a5780d1b0721bf6de385e6ffe0d07dfc7) | [+6](https://github.com/mdqinc/SDL_GameControllerDB/compare/c203690...9db8101) | +| Flynn Alfa 5.0.0 | [163cc5d](https://github.com/mdqinc/SDL_GameControllerDB/tree/163cc5d45e9fc2f1bb2b95ea7eee4bbc9a57955c) | [+29/-8](https://github.com/mdqinc/SDL_GameControllerDB/compare/9db8101...163cc5d) | +| Flynn Bravo 5.0.1 | [7efce7d](https://github.com/mdqinc/SDL_GameControllerDB/tree/7efce7d3f309ec1fa409b1af09153f9eb77fbedf) | [-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/163cc5d...7efce7d) | +| Flynn Charlie 5.0.2 | [e607703](https://github.com/mdqinc/SDL_GameControllerDB/tree/e607703392145343e8aca42be052121c0b7bd1c9) | [+40/-17](https://github.com/mdqinc/SDL_GameControllerDB/compare/7efce7d...e607703) | +| Bradley Alfa 5.1.0 | [2ba9676](https://github.com/mdqinc/SDL_GameControllerDB/tree/2ba96761af795c15e916cc97790b51e09dc0cd54) | [+1/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/e607703...2ba9676) | +| Bradley Charlie 5.1.2 | [4f5d1d4](https://github.com/mdqinc/SDL_GameControllerDB/tree/4f5d1d497985b75f4a83a5de46f596dc4d7f002e) | [+5/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/2ba9676...4f5d1d4) | +| Bradley Delta 5.1.3 | [9b73049](https://github.com/mdqinc/SDL_GameControllerDB/tree/9b73049ee62a2cc862d6ad94c2c777f2e8363a48) | [+4/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/4f5d1d4...9b73049) | +| Bradley Echo 5.1.4 | [6d3801f](https://github.com/mdqinc/SDL_GameControllerDB/tree/6d3801fcfe74b1989de96403b7b560eba72a175c) | [+56/-21](https://github.com/mdqinc/SDL_GameControllerDB/compare/9b73049...6d3801f) | +| Gibbs Alfa 6.0.0 | [0562b00](https://github.com/mdqinc/SDL_GameControllerDB/tree/0562b00eaf5c0308c49d329b79263d2dae1c3a85) | [+8/-2](https://github.com/mdqinc/SDL_GameControllerDB/compare/6d3801f...0562b00) | +| Khan Alfa 6.1.0 | [436c7e3](https://github.com/mdqinc/SDL_GameControllerDB/tree/436c7e3d54a57189ea0ab44d05f36b7cc7ea496c) | [+31/-16](https://github.com/mdqinc/SDL_GameControllerDB/compare/0562b00...436c7e3) | +| Khan Bravo 6.1.1 | [01cca2e](https://github.com/mdqinc/SDL_GameControllerDB/tree/01cca2e77f9bf9f1432be04f876f287eb78297fe) | [+23/-6](https://github.com/mdqinc/SDL_GameControllerDB/compare/436c7e3...01cca2e) | +| Khan Charlie 6.1.2 | [6852946](https://github.com/mdqinc/SDL_GameControllerDB/tree/6852946487534c69b7d228fd4eb8c87cf6966475) | [+25/-15](https://github.com/mdqinc/SDL_GameControllerDB/compare/01cca2e...6852946) | +| Spock Alfa 7.0.0 | [38bda81](https://github.com/mdqinc/SDL_GameControllerDB/tree/38bda816dc786f18493876f7bc30bc12dfd2636a) | [+15/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/6852946...38bda81) | +| Spock Bravo 7.0.1 | [228d980](https://github.com/mdqinc/SDL_GameControllerDB/tree/228d980d3d791e9df3b096472f6b97459f8709fe) | [+7/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/38bda81...228d980) | +| Spock Charlie 7.0.2 | [c5b4df0](https://github.com/mdqinc/SDL_GameControllerDB/tree/c5b4df0e1061175cb11e3ebbf8045178339864a5) | [+3](https://github.com/mdqinc/SDL_GameControllerDB/compare/228d980...c5b4df0) | +| Sulu Alfa 7.1.0 | [a2cf171](https://github.com/mdqinc/SDL_GameControllerDB/tree/a2cf1711b4ebc646a3814705d2fb6aac5707bcae) | [+4/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/c5b4df0...a2cf171) | +| Sulu Bravo 7.1.1 | [cc9f777](https://github.com/mdqinc/SDL_GameControllerDB/tree/cc9f777721f0cb30058d9eef52a295130b734a4a) | [+29/-9](https://github.com/mdqinc/SDL_GameControllerDB/compare/a2cf171...cc9f777) | +| MacReady Alfa 8.0.0 | [c56329f](https://github.com/mdqinc/SDL_GameControllerDB/tree/c56329f4df93fc7a780bdbeae47a9c91447b629c) | [+67/-23](https://github.com/mdqinc/SDL_GameControllerDB/compare/cc9f777...c56329f) | +| MacReady Bravo 8.0.1 | [721b575](https://github.com/mdqinc/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+5/-5](https://github.com/mdqinc/SDL_GameControllerDB/compare/c56329f...721b575) | +| MacReady Charlie 8.0.2 | [721b575](https://github.com/mdqinc/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+0/-0](https://github.com/mdqinc/SDL_GameControllerDB/compare/721b575...721b575) | +| MacReady Delta 8.0.3 | [d4ab609](https://github.com/mdqinc/SDL_GameControllerDB/tree/d4ab609121ee6e687bc3d3a7e80244b3b26d1164) | [+5/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/721b575...d4ab609) | +| MacReady Echo 8.0.4 | [6555d47](https://github.com/mdqinc/SDL_GameControllerDB/tree/6555d47ecb5d9eebac0e3d8cd19a545e9d946c40) | [+2/-0](https://github.com/mdqinc/SDL_GameControllerDB/compare/d4ab609...6555d47) | +| MacReady Foxtrot 8.0.5 | [037d6a1](https://github.com/mdqinc/SDL_GameControllerDB/tree/037d6a1533ed94fbc6a8c71e6f1f9aff1e46208a) | [+47/-14](https://github.com/mdqinc/SDL_GameControllerDB/compare/6555d47...037d6a1) | +| MacReady Golf 8.0.6 | [075c154](https://github.com/mdqinc/SDL_GameControllerDB/tree/075c1549075ef89a397fd7e0663d21e53a2485fd) | [+340/-301](https://github.com/mdqinc/SDL_GameControllerDB/compare/037d6a1...075c154) | diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index e74c14f4c..00f25a9b4 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -740,7 +740,7 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/soh/soh.o2r DESTINATION . COMPONENT ship) endif() find_program(CURL NAMES curl DOC "Path to the curl program. Used to download files.") -execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt OUTPUT_VARIABLE RESULT) +execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt -o ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt OUTPUT_VARIABLE RESULT) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/macosx/Info.plist.in ${CMAKE_BINARY_DIR}/macosx/Info.plist @ONLY) From 860bc57a2a172f07bf38ba41a127e371a0750268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Aug 2025 19:01:33 +0000 Subject: [PATCH 26/98] fix incorrect description (#5752) --- soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c index 093e73eb4..7dbe531d5 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c @@ -1,7 +1,7 @@ /* * File: z_bg_mizu_movebg.c * Overlay: ovl_Bg_Mizu_Movebg - * Description: Kakariko Village Well Water + * Description: Water Temple Moving Objects */ #include "z_bg_mizu_movebg.h" From cc477fbef21a25ac59d056c797e4e04310ec1351 Mon Sep 17 00:00:00 2001 From: Eblo <7004497+Eblo@users.noreply.github.com> Date: Mon, 25 Aug 2025 15:01:50 -0400 Subject: [PATCH 27/98] [Enhancement] Toggle grave hole geometry (#5754) * Add enhancement to toggle grave hole geometry * Replace malloc and vector with fixed-size arrays * Make newSurfaceTypes static --- .../Restorations/GraveHoleJumps.cpp | 72 +++++++++++++++++++ soh/soh/SohGui/SohMenuEnhancements.cpp | 4 ++ 2 files changed, 76 insertions(+) create mode 100644 soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp diff --git a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp new file mode 100644 index 000000000..32157b5ce --- /dev/null +++ b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp @@ -0,0 +1,72 @@ +#include "public/bridge/consolevariablebridge.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "functions.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/resource/type/Scene.h" +#include "soh/resource/type/scenecommand/SceneCommand.h" +#include "soh/resource/type/scenecommand/SetCollisionHeader.h" + +#define CVAR_GRAVE_HOLE_NAME CVAR_ENHANCEMENT("GraveHoles") +#define GRAVE_HOLES_DEFAULT 0 +#define CVAR_GRAVE_HOLE_VALUE CVarGetInteger(CVAR_GRAVE_HOLE_NAME, GRAVE_HOLES_DEFAULT) +#define GRAVEYARD_SCENE_FILEPATH "scenes/shared/spot02_scene/spot02_scene" +#define CUSTOM_SURFACE_TYPE 32 + +const static std::array, std::pair>, 6> graveyardGeometryPatches = { { + // { { startPolygon, endPolygon }, { originalSurfaceType, patchedSurfaceType } } + { { 487, 509 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around graves + { { 651, 658 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around Royal Family Tomb + { { 613, 620 }, { 0, 15 } }, // Grave ledges (Hylian Shield) + { { 623, 630 }, { 0, 15 } }, // Grave ledges (Redead) + { { 633, 640 }, { 0, 15 } }, // Grave ledges (Dampe) + { { 643, 650 }, { 0, 15 } }, // Grave ledges (Royal Family) +} }; + +CollisionHeader* getGraveyardCollisionHeader() { + /* + * Load the graveyard collision header manually. Since its position varies between versions, we cannot directly use + * dspot02_sceneCollisionHeader_003C54. We have to scroll through the scene cmds to get the header the same way the + * game does. + */ + SOH::Scene* scene = + (SOH::Scene*)Ship::Context::GetInstance()->GetResourceManager()->LoadResource(GRAVEYARD_SCENE_FILEPATH).get(); + SOH::ISceneCommand* sceneCmd = nullptr; + for (int i = 0; i < scene->commands.size(); i++) { + auto cmd = scene->commands[i]; + if (cmd->cmdId == SOH::SceneCommandID::SetCollisionHeader) { + sceneCmd = cmd.get(); + break; + } + } + CollisionHeader* graveyardColHeader = (CollisionHeader*)((SOH::SetCollisionHeader*)sceneCmd)->GetRawPointer(); + + /* + * Copy the surface type list and give ourselves some extra space to create another surface type for Link to fall + * into graves. NTSC 1.0's graveyard has 31 surface types, while later versions have 32. The contents of the lists + * are shifted somewhat between versions, so to be safe we just create an extra slot that is not in any version. + */ + static SurfaceType newSurfaceTypes[33]; + memcpy(newSurfaceTypes, graveyardColHeader->surfaceTypeList, sizeof(SurfaceType) * 33); + newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[0] = 0x24000004; + newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[1] = 0xFC8; + graveyardColHeader->surfaceTypeList = newSurfaceTypes; + + return graveyardColHeader; +} + +void ApplyGraveyardGeometryPatches() { + static CollisionHeader* graveyardColHeader = getGraveyardCollisionHeader(); + for (auto& mappingPatch : graveyardGeometryPatches) { + for (int i = mappingPatch.first.first; i <= mappingPatch.first.second; i++) { + CollisionPoly* poly = &graveyardColHeader->polyList[i]; + poly->type = CVAR_GRAVE_HOLE_VALUE ? mappingPatch.second.first : mappingPatch.second.second; + } + } +} + +void RegisterGraveHoleJumps() { + ApplyGraveyardGeometryPatches(); +} + +static RegisterShipInitFunc initFunc_GraveHoleJumps(RegisterGraveHoleJumps, { CVAR_GRAVE_HOLE_NAME }); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 2a40cb23c..f7b571118 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1165,6 +1165,10 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("NGCKaleidoSwitcher")) .Options(CheckboxOptions().Tooltip( "Makes L and R switch pages like on the GameCube. Z opens the Debug Menu instead.")); + AddWidget(path, "Grave Hole Jumps", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("GraveHoles")) + .Options(CheckboxOptions().Tooltip( + "Restores NTSC 1.0 behavior where Link jumps over grave holes and grabs the ledges.")); // Difficulty Options path.sidebarName = "Difficulty"; From bdaf3524406e4916e02ee64cf0cc13bfe119ed24 Mon Sep 17 00:00:00 2001 From: Glought Date: Mon, 25 Aug 2025 12:02:30 -0700 Subject: [PATCH 28/98] Adds "Randomize on Randomizer Generation" options to Audio and Cosmetics Editors (#5387) * Add "Randomize on Randomizer Generation" options to Audio and Cosmetics Editors * Added "Randomize All Music and Sound Effects on Randomizer Generation" to the Audio Editor. * Added "Randomize All on Randomizer Generation" to the Cosmetics Editor. When enabled, these options randomize audio and/or cosmetics during a new randomizer generation. * Added "OnRandomizerGeneration" Hook. * It is executed on Randomizer Generation. * Changed AudioEditor and CosmeticsEditor "Randomize all on Randomizer Generation" options to use the "OnRandomizerGeneration" Hook. * Renamed "OnRandomizerGeneration" to "OnGenerationCompletion. Renamed "GameInteractor_ExecuteOnRandomizerGeneration" to "GameInteractor_ExecuteOnGenerationCompletion" Moved "GameInteractor_ExecuteOnGenerationCompletion" from "GenerateRandomizer" to the end of "GenerateRandomizerImgui". * Removed "GameInteractor_ExecuteOnGenerationCompletion()" from "GameInteractor_Hooks.h" and "GameInteractor_Hooks.cpp" The "OnGenerationCompletion" hook is now called directly at the end of "GenerateRandomizerImgui" in "randomizer.cpp" --------- Co-authored-by: Glought <663343+Glought@users.noreply.github.com> --- soh/soh/Enhancements/audio/AudioEditor.cpp | 15 +++++++++++++++ .../Enhancements/cosmetics/CosmeticsEditor.cpp | 14 ++++++++++++++ .../game-interactor/GameInteractor_HookTable.h | 1 + soh/soh/Enhancements/randomizer/randomizer.cpp | 3 +++ 4 files changed, 33 insertions(+) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 6660bee7d..f031048f2 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -468,8 +468,17 @@ void AudioEditorRegisterOnSceneInitHook() { }); } +void AudioEditorRegisterOnGenerationCompletionHook() { + GameInteractor::Instance->RegisterGameHook([]() { + if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnRandoGen"), 0)) { + AudioEditor_RandomizeAll(); + } + }); +} + void AudioEditor::InitElement() { AudioEditorRegisterOnSceneInitHook(); + AudioEditorRegisterOnGenerationCompletionHook(); } void AudioEditor::DrawElement() { @@ -573,6 +582,12 @@ void AudioEditor::DrawElement() { .Color(THEME_COLOR) .Tooltip( "Enables randomizing all unlocked music and sound effects when you enter a new scene.")); + UIWidgets::CVarCheckbox("Randomize All Music and Sound Effects on Randomizer Generation", + CVAR_AUDIO("RandomizeAllOnRandoGen"), + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables randomizing all unlocked music and sound effects when " + "you generate a new randomizer.")); UIWidgets::CVarCheckbox( "Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"), UIWidgets::CheckboxOptions() diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 8074fa707..314b92b40 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -2382,6 +2382,11 @@ void CosmeticsEditorWindow::DrawElement() { .Color(THEME_COLOR) .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); ImGui::EndDisabled(); + UIWidgets::CVarCheckbox( + "Randomize All on Randomizer Generation", CVAR_COSMETIC("RandomizeAllOnRandoGen"), + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables randomizing all unlocked cosmetics when you generate a new randomizer.")); UIWidgets::CVarCheckbox( "Advanced Mode", CVAR_COSMETIC("AdvancedMode"), UIWidgets::CheckboxOptions() @@ -2589,6 +2594,14 @@ void Cosmetics_RegisterOnSceneInitHook() { }); } +void CosmeticsEditorRegisterOnGenerationCompletionHook() { + GameInteractor::Instance->RegisterGameHook([]() { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnRandoGen"), 0)) { + CosmeticsEditor_RandomizeAll(); + } + }); +} + void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { @@ -2608,6 +2621,7 @@ void CosmeticsEditorWindow::InitElement() { RegisterOnLoadGameHook(); RegisterOnGameFrameUpdateHook(); Cosmetics_RegisterOnSceneInitHook(); + CosmeticsEditorRegisterOnGenerationCompletionHook(); } void CosmeticsEditor_RandomizeAll() { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 51a6ab5a8..3ac408e78 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -68,6 +68,7 @@ DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, (uint8_t optionIndex, uint8_t o DEFINE_HOOK(OnUpdateFileRandomizerOptionSelection, (uint8_t optionIndex)); DEFINE_HOOK(OnUpdateFileNameSelection, (int16_t charCode)); DEFINE_HOOK(OnFileChooseMain, (void* gameState)); +DEFINE_HOOK(OnGenerationCompletion, ()); DEFINE_HOOK(OnSetGameLanguage, ()); DEFINE_HOOK(OnFileDropped, (std::string filePath)); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index b8a4820d8..bbab5ebb3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3800,6 +3800,8 @@ void GenerateRandomizerImgui(std::string seed = "") { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); generated = 1; + + GameInteractor::Instance->ExecuteHooks(); } bool GenerateRandomizer(std::string seed /*= ""*/) { @@ -3809,6 +3811,7 @@ bool GenerateRandomizer(std::string seed /*= ""*/) { } if (CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) == 0) { randoThread = std::thread(&GenerateRandomizerImgui, seed); + return true; } return false; From 7ee708474637325c99845aff5a4cf039e99783ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Aug 2025 19:03:05 +0000 Subject: [PATCH 29/98] logic: remove commented glitched key logic (#5651) this code is obsolete with glitch logic being implemented as tricks --- .../Enhancements/randomizer/3drando/fill.cpp | 6 +- .../randomizer/location_access.cpp | 11 +-- .../dungeons/bottom_of_the_well.cpp | 16 ++-- .../location_access/dungeons/fire_temple.cpp | 46 ++++----- .../dungeons/forest_temple.cpp | 50 +++++----- .../dungeons/ganons_castle.cpp | 20 ++-- .../dungeons/gerudo_training_ground.cpp | 20 ++-- .../dungeons/shadow_temple.cpp | 40 ++++---- .../dungeons/spirit_temple.cpp | 96 +++++++++---------- .../location_access/dungeons/water_temple.cpp | 24 ++--- .../location_access/overworld/market.cpp | 22 ++--- .../overworld/thieves_hideout.cpp | 8 +- soh/soh/Enhancements/randomizer/logic.cpp | 73 +------------- soh/soh/Enhancements/randomizer/logic.h | 11 +-- .../Enhancements/randomizer/randomizerTypes.h | 15 --- 15 files changed, 182 insertions(+), 276 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 2ac5a3592..c53a1477e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -685,9 +685,9 @@ void LookForExternalArea(Region* currentRegion, std::set& alreadyChecke void SetAreas() { auto ctx = Rando::Context::GetInstance(); - // RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here, - // then use those areas to not need to recursivly find ItemLocation areas when an identifying entrance's area - for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) { + // RANDOTODO give entrances an enum like RandomizerCheck, then give them all areas here, + // then use those areas to not need to recursively find ItemLocation areas when identifying entrance's area + for (int regionType = 0; regionType < RR_MAX; regionType++) { Region* region = &areaTable[regionType]; std::set areas = region->GetAllAreas(); std::set regionsToSet = { region }; diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index cb5668b01..f075e1b0c 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -617,7 +617,7 @@ void Region::ResetVariables() { bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge) { // if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if // adult is here it's also Certain Access - if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) { + if (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7)) { if (anyAge) { return Here(condition); } @@ -627,10 +627,9 @@ bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAg } else if (Adult() && logic->IsAdult) { return condition(); // if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and - // meet the adult universe's access condition We only need to do it as child, as only child access matters + // meet the adult universe's access condition. We only need to do it as child, as only child access matters // for this check, as adult access is assumed based on keys - } else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) { - bool result = false; + } else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6))) { // store current age variables bool pastAdult = logic->IsAdult; bool pastChild = logic->IsChild; @@ -638,7 +637,7 @@ bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAg // First check if the check is possible as child logic->IsChild = true; logic->IsAdult = false; - result = condition(); + bool result = condition(); // If so, check again as adult. both have to be true for result to be true if (result) { logic->IsChild = false; @@ -897,7 +896,7 @@ void RegionTable_Init() { RegionTable_Init_GanonsCastle(); // Set parent regions - for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) { + for (uint32_t i = RR_ROOT; i < RR_MAX; i++) { for (LocationAccess& locPair : areaTable[i].locations) { RandomizerCheck location = locPair.GetLocation(); Rando::Context::GetInstance()->GetItemLocation(location)->SetParentRegion((RandomizerRegion)i); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 001ad5d81..451989a44 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -35,7 +35,7 @@ void RegionTable_Init_BottomOfTheWell() { Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}), + Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}), Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}), Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->LoweredWaterInsideBotw && logic->IsChild;}), //Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick @@ -56,7 +56,7 @@ void RegionTable_Init_BottomOfTheWell() { }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_BOTTOM_OF_THE_WELL_INNER_ROOMS, []{return logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}), + Entrance(RR_BOTTOM_OF_THE_WELL_INNER_ROOMS, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}), Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return true;}), Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), }); @@ -79,7 +79,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}), Entrance(RR_BOTTOM_OF_THE_WELL_LIKE_LIKE_CAGE, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), //not sure if this lens check is needed, these holes are a bit too easy to find, but it matches existing logic Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), @@ -105,7 +105,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}), + Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM] = Region("Bottom of the Well Coffin Room", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -207,8 +207,8 @@ void RegionTable_Init_BottomOfTheWell() { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild;}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->LoweredWaterInsideBotw;}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}), @@ -231,7 +231,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE] = Region("Bottom of the Well MQ Locked Cage", SCENE_BOTTOM_OF_THE_WELL, { @@ -239,7 +239,7 @@ void RegionTable_Init_BottomOfTheWell() { EventAccess(&logic->OpenedMiddleHoleMQBotw, []{return logic->HasExplosives();}), }, {}, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM] = Region("Bottom of the Well MQ Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index f57d6bd21..8d8f0ad28 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -20,9 +20,9 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->FireTimer() >= 24;}), - Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked);}), + Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked);}), Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), }); areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, { @@ -43,7 +43,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked;}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked;}), Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return Here(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}), }); @@ -96,11 +96,11 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_3, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 2);}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2);}), Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, []{return true;}), Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, []{return logic->IsAdult && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_FIRE_SOT));}), Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, []{return logic->IsAdult && logic->HasExplosives();}), - Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}), + Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), }); areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Region("Fire Temple Big Lava Room North Goron", SCENE_FIRE_TEMPLE, {}, { @@ -135,8 +135,8 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, logic->FireTimer() >= 56), }, { //Exits - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}), - Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->FireTimer() >= 56 && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->FireTimer() >= 56 && logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", SCENE_FIRE_TEMPLE, {}, { @@ -144,7 +144,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;})), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), }); @@ -163,7 +163,7 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 7);}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return false;}), }); @@ -183,8 +183,8 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->TakeDamage();}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 8);}), - Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 6);}), Entrance(RR_FIRE_TEMPLE_MAP_AREA, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}), }); @@ -195,10 +195,10 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, logic->FireTimer() >= 24), }, { //Exits - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->FireTimer() >= 24 && logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->FireTimer() >= 24 && logic->SmallKeys(SCENE_FIRE_TEMPLE, 6);}), Entrance(RR_FIRE_TEMPLE_MAP_AREA, []{return logic->IsAdult;}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return logic->FireTimer() >= 24 && logic->IsAdult;}), - Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return logic->FireTimer() >= 24 && logic->IsAdult && logic->SmallKeys(RR_FIRE_TEMPLE, 7);}), + Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return logic->FireTimer() >= 24 && logic->IsAdult && logic->SmallKeys(SCENE_FIRE_TEMPLE, 7);}), }); areaTable[RR_FIRE_TEMPLE_MAP_AREA] = Region("Fire Temple Map Region", SCENE_FIRE_TEMPLE, {}, { @@ -241,7 +241,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_CORRIDOR] = Region("Fire Temple Corridor", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 7);}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 7);}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), }); @@ -256,7 +256,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return true;}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8);}), + Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return ctx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}), }); @@ -280,7 +280,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, Here(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER);})), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return true;}), }); @@ -357,7 +357,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return true;}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), }); areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER] = Region("Fire Temple MQ First Room Upper", SCENE_FIRE_TEMPLE, {}, {}, { @@ -485,7 +485,7 @@ void RegionTable_Init_FireTemple() { //Exits // Fewer tunic requirements ends here Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return logic->FireTimer() >= 20;}), - Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2);}), + Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 2);}), Entrance(RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM, []{return logic->HasFireSource() && ((logic->CanUse(RG_FAIRY_BOW) && logic->FireTimer() >= 25) || (ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST) && logic->FireTimer() >= 50)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_SOT)));}), }); @@ -556,7 +556,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, []{return logic->HasExplosives();}), //Implies RR_FIRE_TEMPLE_MQ_LOWER_MAZE access Entrance(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK_CLIMB, []{return logic->HasExplosives() && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME)));}), - Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 3) && logic->CanUse(RG_GORON_TUNIC);}), + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3) && logic->CanUse(RG_GORON_TUNIC);}), }); areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE_BOX_CAGE] = Region("Fire Temple MQ Upper Maze Box Cage", SCENE_FIRE_TEMPLE, {}, { @@ -642,7 +642,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, logic->CanBreakSmallCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}), + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return true;}), //Child has issues navigating the higher points of this room without an equip swapped hookshot Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, []{return Here(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT));}) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT));}), @@ -705,7 +705,7 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, logic->CanKillEnemy(RE_FLARE_DANCER)), }, { Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, []{return logic->CanKillEnemy(RE_FLARE_DANCER);}), - Entrance(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanKillEnemy(RE_FLARE_DANCER) && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanKillEnemy(RE_FLARE_DANCER) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), }); areaTable[RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM] = Region("Fire Temple MQ Scarecrow Room", SCENE_FIRE_TEMPLE, {}, { @@ -718,8 +718,8 @@ void RegionTable_Init_FireTemple() { //Using this dropdown is in N64 logic elsewhere, but not here, probably because it requires good foreknowlege to determine where to land //This would be a logical method to reach the hammer switch without hookshot, but it practically requires access to the area that switch unlocks already. It could also be first child access to PLATFORMS if tricks ever enable that //If a practical use for this drop is found, it should be made a trick - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 4);}), - Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, []{return Here(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->SmallKeys(RR_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, []{return Here(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), }); //The peg knocked down from here could have logical implications for child in the fire maze if tricks to gain height like bomb jumps exist diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index a4a558297..e5c12bc97 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -50,7 +50,7 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_NORTH_CORRIDOR, []{return true;}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}), Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}), - Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}), + Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 1);}), Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, []{return false;}), Entrance(RR_FOREST_TEMPLE_BOSS_REGION, []{return logic->ForestTempleMeg;}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), @@ -171,7 +171,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_WEST_CORRIDOR] = Region("Forest Temple West Corridor", SCENE_FOREST_TEMPLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}), + Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 1);}), Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, []{return logic->CanAttack() || logic->CanUse(RG_NUTS);}), }); @@ -182,14 +182,14 @@ void RegionTable_Init_ForestTemple() { //Exits Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return true;}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslashExceptHammer() && logic->HasItem(RG_GORONS_BRACELET));}), - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, []{return logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, []{return logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}), }); areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Region("Forest Temple NW Corridor Twisted", SCENE_FOREST_TEMPLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), - Entrance(RR_FOREST_TEMPLE_RED_POE_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 3);}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_RED_POE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), }); areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED] = Region("Forest Temple NW Corridor Straightened", SCENE_FOREST_TEMPLE, {}, { @@ -198,7 +198,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return true;}), - Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}), }); areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", SCENE_FOREST_TEMPLE, { @@ -209,7 +209,7 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->ForestTempleJoelle), }, { //Exits - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 3);}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, []{return true;}), }); @@ -238,18 +238,18 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, []{return true;}), - Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}), + Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), }); areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED] = Region("Forest Temple NE Corridor Straightened", SCENE_FOREST_TEMPLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_BLUE_POE_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}), - Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}), + Entrance(RR_FOREST_TEMPLE_BLUE_POE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), + Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 5);}), }); areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED] = Region("Forest Temple NE Corridor Twisted", SCENE_FOREST_TEMPLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}), + Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 5);}), Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, []{return true;}), }); @@ -259,8 +259,8 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}), - Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 5) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE));}), + Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 5);}), + Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 5) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE));}), }); areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Region("Forest Temple Falling Room", SCENE_FOREST_TEMPLE, {}, { @@ -313,7 +313,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 1) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), }); areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Region("Forest Temple MQ Central Region", SCENE_FOREST_TEMPLE, { @@ -382,21 +382,21 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE] = Region("Forest Temple MQ After Block Puzzle", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_FOREST_TEMPLE, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3)), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 3);}), - Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->ForestCanTwistHallway && logic->SmallKeys(RR_FOREST_TEMPLE, 4);}), + Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), + Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->ForestCanTwistHallway && logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), //!QUANTUM LOGIC! //As there is no way in default logic to reach the other possible key use without going through RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, this is logically safe for now //Breaks if there's any other way to RR_FOREST_TEMPLE_MQ_FALLING_ROOM than going through the eye targets in RR_FOREST_TEMPLE_MQ_CENTRAL_AREA //Requires a bow/sling ammo source once ammo logic is done, to avoid edge cases. - Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 2) && Here(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->CanKillEnemy(RE_FLOORMASTER);});}), + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2) && Here(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->CanKillEnemy(RE_FLOORMASTER);});}), }); areaTable[RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY] = Region("Forest Temple MQ Straight Hallway", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_FOREST_TEMPLE, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM, []{return true;}), @@ -489,7 +489,7 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->ForestTempleJoelle), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}), + Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), Entrance(RR_FOREST_TEMPLE_MQ_3_STALFOS_ROOM, []{return true;}), }); @@ -524,8 +524,8 @@ void RegionTable_Init_ForestTemple() { //!QUANTUM LOGIC! //This key logic assumes that you can get to falling room either by spending the 5th key here, or by wasting a key in falling room itself. //While being the 5th key makes this simpler in theory, if a different age can waste the key compared to reaching this room it breaks - Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 5) && Here(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE);});}), - Entrance(RR_FOREST_TEMPLE_MQ_TORCH_SHOT_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 6);}), + Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 5) && Here(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE);});}), + Entrance(RR_FOREST_TEMPLE_MQ_TORCH_SHOT_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 6);}), Entrance(RR_FOREST_TEMPLE_MQ_3_STALFOS_ROOM, []{return true;}), }); @@ -538,7 +538,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE);}), - Entrance(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 6);}), + Entrance(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 6);}), }); areaTable[RR_FOREST_TEMPLE_MQ_FALLING_ROOM] = Region("Forest Temple MQ Falling Room", SCENE_FOREST_TEMPLE, {}, { @@ -547,7 +547,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, []{return true;}), - Entrance(RR_FOREST_TEMPLE_MQ_AMY_ROOM, []{return logic->SmallKeys(RR_FOREST_TEMPLE, 6);}), + Entrance(RR_FOREST_TEMPLE_MQ_AMY_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 6);}), }); areaTable[RR_FOREST_TEMPLE_MQ_AMY_ROOM] = Region("Forest Temple MQ Amy Room", SCENE_FOREST_TEMPLE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 8571ba384..a0e1f54d1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -118,7 +118,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->LightTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), + EventAccess(&logic->LightTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), @@ -128,10 +128,10 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_GANONS_CASTLE, 1)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_GANONS_CASTLE, 2)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 1)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), }, {}); #pragma endregion @@ -243,12 +243,12 @@ void RegionTable_Init_GanonsCastle() { }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return true;}), - Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 3) && Here(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, []{return logic->BlueFire();});}), + Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3) && Here(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, []{return logic->BlueFire();});}), }); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle MQ Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits - Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 3);}), + Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3);}), //This assumes there's no way for child to have blue fire and not adult. Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM, []{return logic->IsAdult && logic->BlueFire();}), }); @@ -388,12 +388,12 @@ void RegionTable_Init_GanonsCastle() { }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, []{return true;}), - Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, []{return logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2);}), }); areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT] = Region("Ganon's Castle MQ Light Trial Boulder Room Front", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits - Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_TRIFORCE_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_TRIFORCE_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2);}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}), }); @@ -405,7 +405,7 @@ void RegionTable_Init_GanonsCastle() { //Exits //I got the trick going backwards, but only while taking damage. this isn't relevant anyway though Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}), - Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}), }); areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Light Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 6c891abc0..68e1184ab 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -35,14 +35,14 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 4)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 6)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 7)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 9)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9)), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 9);}), + Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9);}), }); areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Ground Central Maze Right", SCENE_GERUDO_TRAINING_GROUND, {}, { @@ -126,7 +126,7 @@ void RegionTable_Init_GerudoTrainingGround() { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return true;}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM, []{return ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 1);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 1);}), //It's possible to use the torch in RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM with flame storage to light these Entrance(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->HasFireSource();});}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT));});}), @@ -145,8 +145,8 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, true), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 1);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 1);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3);}), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER] = Region("Gerudo Training Ground MQ Center", SCENE_GERUDO_TRAINING_GROUND, { @@ -158,7 +158,7 @@ void RegionTable_Init_GerudoTrainingGround() { }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3);}), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM] = Region("Gerudo Training Ground MQ Sand Room", SCENE_GERUDO_TRAINING_GROUND, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d276fc418..e5d2610f5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -48,7 +48,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}), + Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 1);}), Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return false;}), }); @@ -59,11 +59,11 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), @@ -74,7 +74,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, { @@ -82,15 +82,15 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()), - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4)), LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4);}), }); areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, {}, { @@ -112,7 +112,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS);}) + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS);}) }); #pragma endregion @@ -138,7 +138,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}), - Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), }); //Assumes we're in the "main" area and needed lens to enter. logic will need changes if a void warp puts us somewhere weird @@ -164,7 +164,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->HasExplosives() && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), }); @@ -190,7 +190,7 @@ void RegionTable_Init_ShadowTemple() { //Room exists for if it's ever possible to go backwards or void warp into the middle of shadow areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily }); @@ -226,7 +226,7 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}), - Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { @@ -274,7 +274,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), //We need to assume we can get here with or without the glass platforms - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, { @@ -287,7 +287,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), }); @@ -316,7 +316,7 @@ void RegionTable_Init_ShadowTemple() { //Exits //child can make it using the wind strat Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", SCENE_SHADOW_TEMPLE, { @@ -329,7 +329,7 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->ShadowShortcutBlock;}), - Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5);}), //funnily enough, the wheel jump seems to be in logic as there's no strength requirement in N64 Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); @@ -384,7 +384,7 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 6);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", SCENE_SHADOW_TEMPLE, {}, { @@ -394,7 +394,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), }); #pragma endregion diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index e2a13ecc1..f0779358d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -43,17 +43,17 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), + Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}), }); areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) || (logic->TakeDamage() && (logic->CanJumpslashExceptHammer() || logic->HasProjectile(HasProjectileAge::Child))) || - (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslashExceptHammer())))), + (logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslashExceptHammer())))), LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, logic->CanBreakPots()), }, { //Exits @@ -64,46 +64,46 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslashExceptHammer())), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3)), LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}), }); areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Region("Spirit Temple Central Chamber", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) && + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), - LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) && + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), + LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)), - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives() && logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_HOOKSHOT)) || - (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) || - (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2))), - LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) && + (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) || + (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2))), + LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) || - (ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) || - (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), - LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), - LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)), + (ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) || + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), + LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots() && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, []{return logic->CanJumpslashExceptHammer() || logic->HasExplosives();}), - Entrance(RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS);}), + Entrance(RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS);}), Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return true;}), // RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, []{return ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT);}), @@ -111,11 +111,11 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_OUTDOOR_HANDS] = Region("Spirit Temple Outdoor Hands", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->HasExplosives()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)), - LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->HasExplosives()) || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasExplosives()), }, { //Exits - Entrance(RR_DESERT_COLOSSUS, []{return (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)) || (logic->CanUse(RG_SILVER_GAUNTLETS) && ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->HasExplosives()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)));}), + Entrance(RR_DESERT_COLOSSUS, []{return (logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)) || (logic->CanUse(RG_SILVER_GAUNTLETS) && ((logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->HasExplosives()) || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)));}), }); areaTable[RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Central Locked Door", SCENE_SPIRIT_TEMPLE, {}, { @@ -127,7 +127,7 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}), + Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}), }); areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", SCENE_SPIRIT_TEMPLE, {}, { @@ -250,7 +250,7 @@ void RegionTable_Init_SpiritTemple() { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}), //This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys - Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE] = Region("Spirit Temple MQ Under Like Like", SCENE_SPIRIT_TEMPLE, {}, { @@ -259,7 +259,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Exits //This covers adult access only, as child arrives here from the other side of this door - Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanHitSwitch();}), }); @@ -274,7 +274,7 @@ void RegionTable_Init_SpiritTemple() { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanHitSwitch();}), //This exit only governs child possible access, adult access starts on the other side so never checks this - Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", SCENE_SPIRIT_TEMPLE, {}, { @@ -292,7 +292,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Exits //we check possible adult access directly in MQSpiritSharedBrokenWallRoom, so this exit only covers Certain Access - Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), //We can use Here instead of Shared here because adult will never need to rely on child access to reach this room, and adult access is Certain Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME));});}), Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->CanUse(RG_SONG_OF_TIME);}), @@ -311,12 +311,12 @@ void RegionTable_Init_SpiritTemple() { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}), //This door causes the Universes to merge as it requires 7 keys for both ages - Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}), }); @@ -341,7 +341,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone - LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()), }, { //Exits //if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH from here is ever relevant, there needs to be an event to handle the block @@ -359,13 +359,13 @@ void RegionTable_Init_SpiritTemple() { //We only need 4 keys, access to Shield hand and longshot to reach Gauntlets hand, as if we waste the 5th key we have given ourselves Gauntlets hand access through child climb //This exit handles that possibility as cleanly as possible without quantum logic, but will not survive glitch logic //logic->CanKillEnemy(RE_FLOORMASTER) is implied - Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->CanUse(RG_LONGSHOT);}), - Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}), }); @@ -398,7 +398,7 @@ void RegionTable_Init_SpiritTemple() { Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_MEGATON_HAMMER);}), Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, []{return true;}), Entrance(RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", SCENE_SPIRIT_TEMPLE, {}, { @@ -412,7 +412,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM] = Region("Spirit Temple MQ Symphony Room", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), //Implies CanPassEnemy(RE_MOBLIN_CHIEF) Entrance(RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); @@ -432,9 +432,9 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME);}), - Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", SCENE_SPIRIT_TEMPLE, {}, { @@ -497,7 +497,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}), Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 03cc44645..2efc2fb1e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -28,13 +28,13 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}), Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), Entrance(RR_WATER_TEMPLE_WEST_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->SmallKeys(RR_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}), Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, []{return logic->CanWaterTempleMiddle;}), Entrance(RR_WATER_TEMPLE_HIGH_WATER, []{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}), Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->CanWaterTempleMiddle)));}), - Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, []{return logic->CanWaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, []{return logic->CanWaterTempleHigh && logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}), }); @@ -80,7 +80,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_NORTH_LOWER] = Region("Water Temple North Lower", SCENE_WATER_TEMPLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}), - Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, []{return (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS))) && logic->SmallKeys(RR_WATER_TEMPLE, 4);}), + Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, []{return (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS))) && logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), }); areaTable[RR_WATER_TEMPLE_BOULDERS_LOWER] = Region("Water Temple Boulders Lower", SCENE_WATER_TEMPLE, {}, { @@ -88,7 +88,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) || Here(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->IsAdult && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));})), }, { //Exits - Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->SmallKeys(RR_WATER_TEMPLE, 4);}), + Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), Entrance(RR_WATER_TEMPLE_BLOCK_ROOM, []{return true;}), Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP))) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_IRON_BOOTS));}), }); @@ -113,7 +113,7 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, []{return true;}), Entrance(RR_WATER_TEMPLE_JETS_ROOM, []{return logic->IsAdult;}), - Entrance(RR_WATER_TEMPLE_BOSS_KEY_ROOM, []{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE))) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_BOSS_KEY_ROOM, []{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE))) && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), }); areaTable[RR_WATER_TEMPLE_BOSS_KEY_ROOM] = Region("Water Temple Boss Key Room", SCENE_WATER_TEMPLE, { @@ -126,7 +126,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE)) || logic->IsChild || logic->HasItem(RG_SILVER_SCALE)) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE)) || logic->IsChild || logic->HasItem(RG_SILVER_SCALE)) && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), }); areaTable[RR_WATER_TEMPLE_SOUTH_LOWER] = Region("Water Temple South Lower", SCENE_WATER_TEMPLE, {}, { @@ -158,7 +158,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER] = Region("Water Temple Central Pillar Lower", SCENE_WATER_TEMPLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->SmallKeys(RR_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, []{return logic->CanWaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}), }); @@ -168,7 +168,7 @@ void RegionTable_Init_WaterTemple() { EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())), + LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(SCENE_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}), @@ -223,8 +223,8 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_RANG_FALLING_PLATFORM_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))), }, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_WATER_TEMPLE, 4);}), - Entrance(RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), + Entrance(RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), }); areaTable[RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Region("Water Temple Dragon Pillars Room", SCENE_WATER_TEMPLE, {}, { @@ -327,7 +327,7 @@ void RegionTable_Init_WaterTemple() { //Jumping across is possible but a trick due to the janky ledge Entrance(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, []{return logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}), //room access is (logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) - Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 1) && logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT);}), //this swimless jump with irons may be a trick as you have to put irons on quite late. Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, []{return (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->MQWaterLevel(WL_LOW_OR_MID);}), }); @@ -553,7 +553,7 @@ void RegionTable_Init_WaterTemple() { //This room exists to hold the wonderitems that drop from the emblems here. Specifically this assumes you are standing on the final ledge areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", SCENE_WATER_TEMPLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, []{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, []{return true;}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, []{return (logic->MQWaterStalfosPit && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->MQWaterStalfosPit && logic->CanUse(RG_LONGSHOT);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 4f62d437f..2dc140284 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -192,17 +192,17 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", SCENE_TREASURE_BOX_SHOP, {}, { //Locations LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp index 0a70e77e8..d195c71fd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp @@ -9,7 +9,7 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_1_TORCH_CELL] = Region("Thieves Hideout 1 Torch Cell", SCENE_THIEVES_HIDEOUT, { //Events EventAccess(&logic->THCouldFree1TorchCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return logic->SmallKeys(RR_GF_OUTSKIRTS, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(&logic->THRescuedAllCarpenters, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), }, { //Locations LOCATION(RC_TH_1_TORCH_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), @@ -27,7 +27,7 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_DOUBLE_CELL] = Region("Thieves Hideout Double Cell", SCENE_THIEVES_HIDEOUT, { //Events EventAccess(&logic->THCouldFreeDoubleCellCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(RR_GF_OUTSKIRTS, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), }, { //Locations LOCATION(RC_TH_DOUBLE_CELL_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), @@ -50,7 +50,7 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_DEAD_END_CELL] = Region("Thieves Hideout Dead End Cell", SCENE_THIEVES_HIDEOUT, { //Events EventAccess(&logic->TH_CouldFreeDeadEndCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(RR_GF_OUTSKIRTS, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), }, { //Locations LOCATION(RC_TH_DEAD_END_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), @@ -64,7 +64,7 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_STEEP_SLOPE_CELL] = Region("Thieves Hideout Steep Slope Cell", SCENE_THIEVES_HIDEOUT, { //Events EventAccess(&logic->THCouldRescueSlopeCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(RR_GF_OUTSKIRTS, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), }, { //Locations LOCATION(RC_TH_STEEP_SLOPE_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3c0c8345e..fa275480d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1366,80 +1366,11 @@ bool Logic::CanTriggerLACS() { (ctx->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); } -bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { - return SmallKeys(dungeon, requiredAmount, requiredAmount); -} - -bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { +bool Logic::SmallKeys(s16 scene, uint8_t requiredAmount) { if (HasItem(RG_SKELETON_KEY)) { return true; } - switch (dungeon) { - case RR_FOREST_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotJump_Boots) >= - static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHoverBoost) >= - static_cast(GlitchDifficulty::NOVICE) || (GetDifficultyValueFromString(GlitchHover) >= - static_cast(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= - static_cast(GlitchDifficulty::INTERMEDIATE)))) { return ForestTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_FOREST_TEMPLE) >= requiredAmountGlitchless; - - case RR_FIRE_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= - static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= - static_cast(GlitchDifficulty::INTERMEDIATE))) { return FireTempleKeys >= requiredAmountGlitched; - }*/ - // If the Fire Temple loop lock is removed, Small key Count is set to 1 before starting - return GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless; - - case RR_WATER_TEMPLE: - /*if (IsGlitched && (false)) { - return WaterTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless; - - case RR_SPIRIT_TEMPLE: - /*if (IsGlitched && (false)) { - return SpiritTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless; - - case RR_SHADOW_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= - static_cast(GlitchDifficulty::NOVICE))) { return ShadowTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless; - - case RR_BOTTOM_OF_THE_WELL: - /*if (IsGlitched && (false)) { - return BottomOfTheWellKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; - - case RR_GERUDO_TRAINING_GROUND: - /*if (IsGlitched && (false)) { - return GerudoTrainingGroundsKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless; - - case RR_GANONS_CASTLE: - /*if (IsGlitched && (false)) { - return GanonsCastleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless; - - case RR_MARKET_TREASURE_CHEST_GAME: - /*if (IsGlitched && (false)) { - return TreasureGameKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless; - - case RR_GF_OUTSKIRTS: - return GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless; - - default: - return false; - } + return GetSmallKeyCount(scene) >= requiredAmount; } std::map Logic::RandoGetToEquipFlag = { diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 2bfea75e9..aaab8fd4c 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -18,14 +18,6 @@ enum class GlitchType { EquipSwap, }; -enum class GlitchDifficulty { - NOVICE = 1, - INTERMEDIATE, - ADVANCED, - EXPERT, - HERO, -}; - class Logic { public: bool noVariable = false; @@ -194,8 +186,7 @@ class Logic { bool HasItem(RandomizerGet itemName); bool HasBossSoul(RandomizerGet itemName); bool CanOpenOverworldDoor(RandomizerGet itemName); - bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount); - bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); + bool SmallKeys(s16 scene, uint8_t requiredAmount); bool CanOpenUnderwaterChest(); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c2b9cbbdd..806488a61 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1077,21 +1077,6 @@ typedef enum { RR_GANONS_CASTLE_ESCAPE, RR_GANONS_CASTLE_GANON_ARENA, - RR_MARKER_AREAS_END, // Used for area key count - - // DUNGEONS - RR_DEKU_TREE, - RR_DODONGOS_CAVERN, - RR_JABU_JABUS_BELLY, - RR_FOREST_TEMPLE, - RR_FIRE_TEMPLE, - RR_WATER_TEMPLE, - RR_SPIRIT_TEMPLE, - RR_SHADOW_TEMPLE, - RR_BOTTOM_OF_THE_WELL, - RR_ICE_CAVERN, - RR_GERUDO_TRAINING_GROUND, - RR_GANONS_CASTLE, RR_MAX, } RandomizerRegion; From 6e6f8dcc9d16b252fd88a224e8b5617fc70e6a57 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Mon, 25 Aug 2025 12:03:13 -0700 Subject: [PATCH 30/98] build: add -Wformat-security (#5646) On some distros format-security is turned on to detect possible issues with non-string literals as format strings Let's explicitly turn it on and fix the ImgUi text formatting to avoid compile issues on those platforms Signed-off-by: William Casarin --- soh/CMakeLists.txt | 3 +++ soh/soh/Enhancements/Presets/Presets.cpp | 2 +- soh/soh/Enhancements/randomizer/Plandomizer.cpp | 14 +++++++------- .../randomizer/randomizer_check_tracker.cpp | 4 ++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 00f25a9b4..e6e2a3181 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -502,6 +502,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wno-error + -Wformat-security -Wno-return-type -Wno-unused-parameter -Wno-unused-function @@ -529,6 +530,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") elseif (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch") target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wno-error + -Wformat-security -Wno-return-type -Wno-unused-parameter -Wno-unused-function @@ -579,6 +581,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wno-error + -Wformat-security -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index b84cb95ca..0132efd6c 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -395,7 +395,7 @@ void PresetsCustomWidget(WidgetInfo& info) { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::AlignTextToFramePadding(); - ImGui::Text(name.c_str()); + ImGui::Text("%s", name.c_str()); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { ImGui::TableNextColumn(); DrawSectionCheck(name, !info.presetValues["blocks"].contains(blockInfo[i].names[1]), &info.apply[i], diff --git a/soh/soh/Enhancements/randomizer/Plandomizer.cpp b/soh/soh/Enhancements/randomizer/Plandomizer.cpp index 4e03e8b8f..06bb69003 100644 --- a/soh/soh/Enhancements/randomizer/Plandomizer.cpp +++ b/soh/soh/Enhancements/randomizer/Plandomizer.cpp @@ -647,7 +647,7 @@ void PlandomizerOverlayText(std::pair drawObject) { imageMax.y - ImGui::CalcTextSize(std::to_string(drawObject.second).c_str()).y - 2); ImGui::SetCursorScreenPos(textPos); - ImGui::Text(std::to_string(drawObject.second).c_str()); + ImGui::Text("%s", std::to_string(drawObject.second).c_str()); // Overlay item info if (drawObject.first.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && @@ -665,7 +665,7 @@ void PlandomizerOverlayText(std::pair drawObject) { ImGui::SetCursorScreenPos(textPos); std::string overlayText = "+"; overlayText += extractNumberInParentheses(drawObject.first.GetName().english.c_str()); - ImGui::Text(overlayText.c_str()); + ImGui::Text("%s", overlayText.c_str()); } if (drawObject.first.GetRandomizerGet() >= RG_FOREST_TEMPLE_BOSS_KEY && drawObject.first.GetRandomizerGet() <= RG_GANONS_CASTLE_BOSS_KEY) { @@ -678,7 +678,7 @@ void PlandomizerOverlayText(std::pair drawObject) { break; } } - ImGui::Text(shortName.c_str()); + ImGui::Text("%s", shortName.c_str()); } if (drawObject.first.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && drawObject.first.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { @@ -691,7 +691,7 @@ void PlandomizerOverlayText(std::pair drawObject) { break; } } - ImGui::Text(shortName.c_str()); + ImGui::Text("%s", shortName.c_str()); } } @@ -1066,7 +1066,7 @@ void PlandomizerDrawHintsWindow() { ImGui::SeparatorText(hintData.hintName.c_str()); ImGui::Text("Current Hint: "); ImGui::SameLine(); - ImGui::TextWrapped(hintData.hintText.c_str()); + ImGui::TextWrapped("%s", hintData.hintText.c_str()); if (spoilerHintData.size() > 0) { hintInputText = plandoHintData[index].hintText.c_str(); @@ -1115,9 +1115,9 @@ void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) { auto randoArea = Rando::StaticData::GetLocation(checkID)->GetArea(); if (rcArea == RCAREA_INVALID || rcArea == randoArea) { ImGui::TableNextColumn(); - ImGui::TextWrapped(spoilerData.checkName.c_str()); + ImGui::TextWrapped("%s", spoilerData.checkName.c_str()); ImGui::TableNextColumn(); - ImGui::TextWrapped(spoilerData.checkRewardItem.GetName().english.c_str()); + ImGui::TextWrapped("%s", spoilerData.checkRewardItem.GetName().english.c_str()); ImGui::TableNextColumn(); PlandomizerDrawItemSlots(index); if (plandoLogData[index].checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d6334b6a0..37cb9f549 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1085,7 +1085,7 @@ void CheckTrackerWindow::DrawElement() { totalChecksSS << totalChecksAvailable << " Available / "; } totalChecksSS << totalChecksGotten << " Checked / " << totalChecks << " Total"; - ImGui::Text(totalChecksSS.str().c_str()); + ImGui::Text("%s", totalChecksSS.str().c_str()); UIWidgets::PaddedSeparator(); @@ -1194,7 +1194,7 @@ void CheckTrackerWindow::DrawElement() { } } - ImGui::Text(areaTotalsSS.str().c_str()); + ImGui::Text("%s", areaTotalsSS.str().c_str()); UIWidgets::Tooltip(areaTotalsTooltipSS.str().c_str()); } else { ImGui::Text("???"); From d8453b2b68f5395f9bdf5279701db59c99b6c274 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Mon, 25 Aug 2025 15:03:23 -0400 Subject: [PATCH 31/98] Prevent MQ Spirit softlock with increased crawl speed (#5667) * disable crawl speed increase if MQ Spirit boulder exists * bring max speed back to 5 --- soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp | 14 ++++++++++++-- soh/soh/SohGui/SohMenuEnhancements.cpp | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp index 896f07973..7ada74e98 100644 --- a/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp +++ b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp @@ -1,4 +1,5 @@ #include +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" #include "global.h" @@ -102,8 +103,17 @@ void CrawlSpeed_Register() { COND_VB_SHOULD(VB_CRAWL_SPEED_INCREASE, shouldRegister, { Player* player = GET_PLAYER(gPlayState); - IncreaseCrawlSpeed(player, gPlayState); - *should = false; + bool isMQ = ResourceMgr_IsGameMasterQuest(); + bool boulderExists = !Flags_GetSwitch(gPlayState, 5); + bool excludeSpiritMQBoulder = + (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE && player->actor.world.pos.z < -545.0f && + player->actor.world.pos.z > -630.0f && isMQ && boulderExists); + if (excludeSpiritMQBoulder) { + *should = true; + } else { + IncreaseCrawlSpeed(player, gPlayState); + *should = false; + } }); } diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index f7b571118..6a5585f95 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -468,7 +468,7 @@ void SohMenu::AddMenuEnhancements() { .Options(IntSliderOptions().Min(0).Max(5).DefaultValue(0).Format("+%d")); AddWidget(path, "Crawl Speed %dx", WIDGET_CVAR_SLIDER_INT) .CVar(CVAR_ENHANCEMENT("CrawlSpeed")) - .Options(IntSliderOptions().Min(1).Max(4).DefaultValue(1).Format("%dx")); + .Options(IntSliderOptions().Min(1).Max(5).DefaultValue(1).Format("%dx")); AddWidget(path, "Exclude Glitch-Aiding Crawlspaces", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("GlitchAidingCrawlspaces")) .PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 0) == 1; }) From 4c269cab30b2a278302e6c4096a6202338bba305 Mon Sep 17 00:00:00 2001 From: Eblo <7004497+Eblo@users.noreply.github.com> Date: Mon, 25 Aug 2025 15:51:50 -0400 Subject: [PATCH 32/98] Add restoration for NTSC 1.0 shutter door range (#5757) --- .../Restorations/WideShutterDoorRanges.cpp | 31 +++++++++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 8 +++++ soh/soh/SohGui/SohMenuEnhancements.cpp | 4 +++ .../actors/ovl_Door_Shutter/z_door_shutter.c | 2 +- 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp diff --git a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp new file mode 100644 index 000000000..8f5fc4f30 --- /dev/null +++ b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp @@ -0,0 +1,31 @@ +#include "public/bridge/consolevariablebridge.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +} + +#define CVAR_WIDE_SHUTTER_DOOR_RANGE CVAR_ENHANCEMENT("WideShutterDoorRange") +#define WIDE_SHUTTER_DOOR_RANGE_DEFAULT 0 +#define CVAR_WIDE_SHUTTER_DOOR_RANGE_VALUE CVarGetInteger(CVAR_WIDE_SHUTTER_DOOR_RANGE, WIDE_SHUTTER_DOOR_RANGE_DEFAULT) + +// The X range is 70 on NTSC 1.0 and 50 in later versions. The Y range is 15 in any version. +// https://github.com/zeldaret/oot/blob/6ecb84097c1a9a8426f3815c84aa6a5d49ad5804/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c#L248-L259 +#define SHUTTER_DOOR_RANGE_X 70 +#define SHUTTER_DOOR_RANGE_Y 15 + +void RegisterWideShutterDoorRange() { + COND_VB_SHOULD(VB_BE_NEAR_DOOR_SHUTTER, CVAR_WIDE_SHUTTER_DOOR_RANGE_VALUE, { + DoorShutter* doorShutter = va_arg(args, DoorShutter*); + Vec3f relPlayerPos = *va_arg(args, Vec3f*); + // Jabu-Jabu door, Phantom Ganon bars, Gohma door, or boss door + if (doorShutter->unk_16C == 3 || doorShutter->unk_16C == 4 || doorShutter->unk_16C == 5 || + doorShutter->unk_16C == 7) { + *should = (SHUTTER_DOOR_RANGE_X < fabsf(relPlayerPos.x) || SHUTTER_DOOR_RANGE_Y < fabsf(relPlayerPos.y)); + } + }); +} + +static RegisterShipInitFunc initFunc_WideShutterDoorRange(RegisterWideShutterDoorRange, + { CVAR_WIDE_SHUTTER_DOOR_RANGE }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 09defd088..7e517155b 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2245,6 +2245,14 @@ typedef enum { // #### `args` // - `*EnBox` VB_CHEST_USE_ICE_EFFECT, + + // #### `result` + // ```c + // arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y) + // ``` + // #### `args` + // - `*DoorShutter` + VB_BE_NEAR_DOOR_SHUTTER, } GIVanillaBehavior; #endif diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 6a5585f95..26eb741d5 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1165,6 +1165,10 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("NGCKaleidoSwitcher")) .Options(CheckboxOptions().Tooltip( "Makes L and R switch pages like on the GameCube. Z opens the Debug Menu instead.")); + AddWidget(path, "Wide Door Ranges", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("WideShutterDoorRange")) + .Options(CheckboxOptions().Tooltip("Restores the wider range of certain shutter doors from NTSC 1.0.\n" + "Notably affects Jabu-Jabu and boss doors.")); AddWidget(path, "Grave Hole Jumps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("GraveHoles")) .Options(CheckboxOptions().Tooltip( diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 1a491064a..ea983771f 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -335,7 +335,7 @@ f32 func_80996840(PlayState* play, DoorShutter* this, f32 arg2, f32 arg3, f32 ar sp28.y = player->actor.world.pos.y + arg2; sp28.z = player->actor.world.pos.z; Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &sp28); - if (arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)) { + if (GameInteractor_Should(VB_BE_NEAR_DOOR_SHUTTER, arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y), this, &sp1C)) { return FLT_MAX; } else { return sp1C.z; From 7b3809366575c14a23d3ca781ee9f399da5c7d48 Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Tue, 26 Aug 2025 21:34:29 +0200 Subject: [PATCH 33/98] [TWEAK] Localization support for the Notification System (#5751) * Localization support * stick/nuts updrage french wording * forgot german questItem and function adaptation for these * names * clang * name + clang * should be the last one :derp: * German typo --- .../Enhancements/randomizer/hook_handlers.cpp | 50 ++- soh/soh/util.cpp | 378 +++++++++++++++++- 2 files changed, 416 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 9e77d27c4..454a892a4 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1,4 +1,4 @@ -#include +#include #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/enhancementTypes.h" @@ -1026,17 +1026,55 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } if (item00->itemEntry.modIndex == MOD_NONE) { + std::string message; + + switch (gSaveContext.language) { + case LANGUAGE_FRA: + message = "Vous obtenez: "; + break; + case LANGUAGE_GER: + message = "Du erhältst: "; + break; + case LANGUAGE_ENG: + default: + message = "You found "; + break; + } + Notification::Emit({ .itemIcon = GetTextureForItemId(item00->itemEntry.itemId), - .message = "You found ", + .message = message, .suffix = SohUtils::GetItemName(item00->itemEntry.itemId), }); } else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) { + std::string message; + std::string itemName; + + switch (gSaveContext.language) { + case LANGUAGE_FRA: + message = "Vous obtenez: "; + itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId) + .GetName() + .french; + break; + case LANGUAGE_GER: + message = "Du erhältst: "; + itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId) + .GetName() + .german; + break; + case LANGUAGE_ENG: + default: + message = "You found "; + itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId) + .GetName() + .english; + break; + } + Notification::Emit({ - .message = "You found ", - .suffix = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId) - .GetName() - .english, + .message = message, + .suffix = itemName, }); } diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index a991c35ca..bd551f937 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -7,6 +7,7 @@ #include #include #include "Enhancements/randomizer/randomizerTypes.h" +#include std::vector sceneNames = { "Inside the Deku Tree", @@ -121,7 +122,7 @@ std::vector sceneNames = { "Treasure Chest Room", }; -std::vector itemNames = { +std::vector itemNamesEng = { "Deku Stick", "Deku Nut", "Bomb", @@ -280,7 +281,325 @@ std::vector itemNames = { "Deku Nut Upgrade (40)", }; -std::vector questItemNames = { +std::vector itemNamesFra = { + "Bâton Mojo", + "Noix Mojo", + "Bombe", + "Arc des Fées", + "Flèche de Feu", + "Feu de Din", + "Lance-Pierre des Fées", + "Ocarina des Fées", + "Ocarina du Temps", + "Missile Teigneux", + "Grappin", + "Super Grappin", + "Flèche de Glace", + "Vent de Farore", + "Boomerang", + "Monocle de Vérité", + "Haricot Magique", + "Masse des Titans", + "Flèche de Lumière", + "Amour de Nayru", + "Bouteille Vide", + "Potion Rouge", + "Potion Verte", + "Potion Bleue", + "Fée en Bouteille", + "Poisson", + "Lait Lon Lon et Bouteille", + "Lettre de Ruto", + "Flamme Bleue", + "Insectes", + "Grand Spectre", + "Lait Lon Lon (Demi)", + "Spectre", + "Oeuf Suspect", + "Poule", + "Lettre de Zelda", + "Masque Renard", + "Masque de Mort", + "Masque du Fantôme", + "Capuche de Lapin", + "Masque Goron", + "Masque Zora", + "Masque Gerudo", + "Masque de Vérité", + "ÉPUISÉ", + "Oeuf de Poche", + "Cocotte de Poche", + "Cojiro", + "Champignon Suspect", + "Potion Suspecte", + "Scie du Chasseur", + "Épée Goron (Cassée)", + "Ordonnance", + "Crapaud-qui-louche", + "Super Gouttes", + "Certificat", + "Arc des Fées & Flèche de Feu", + "Arc des Fées & Flèche de Glace", + "Arc des Fées & Flèche de Lumière", + "Épée Kokiri", + "Épée de Légende", + "Lame des Géants & Épée Biggoron", + "Bouclier Mojo", + "Bouclier Hylien", + "Bouclier Miroir", + "Tunique Kokiri", + "Tunique Goron", + "Tunique Zora", + "Bottes Kokiri", + "Bottes de Plomb", + "Bottes des Airs", + "Sac de Graines (30)", + "Sac de Graines (40)", + "Sac de Graines (50)", + "Carquois (30)", + "Grand Carquois (40)", + "Énorme Grand Carquois (50)", + "Sac de Bombes (20)", + "Gros Sac de Bombes (30)", + "Énorme Sac de Bombes (40)", + "Bracelet Goron", + "Gantelets d'Argent", + "Gantelets d'Or", + "Écaille d'Argent", + "Écaille d'Or", + "Lame des Géants (Cassée)", + "Grande Bourse", + "Bourse de Géant", + "Graines Mojo (5)", + "Canne à Pêche", + "Menuet des Bois", + "Boléro du Feu", + "Sérénade de l'Eau", + "Requiem de l'Esprit", + "Nocturne de l'Ombre", + "Prélude de la Lumière", + "Berceuse de Zelda", + "Chant d'Epona", + "Chant de Saria", + "Chant du Soleil", + "Chant du Temps", + "Chant des Tempêtes", + "Médaillon de la Forêt", + "Médaillon du Feu", + "Médaillon de l'Eau", + "Médaillon de l'Esprit", + "Médaillon de l'Ombre", + "Médaillon de la Lumière", + "Émeraude Kokiri", + "Rubis Goron", + "Saphir Zora", + "Pierre de Souffrance", + "Carte Gerudo", + "Symbole de Skulltula d'Or", + "Réceptacle de Coeur", + "Quart de Coeur", + "Clé du Boss", + "Boussole", + "Carte du Donjon", + "Petite Clé", + "Petite Magie", + "Grande Magie", + "Quart de Coeur", + "[Retiré]", + "[Retiré]", + "[Retiré]", + "[Retiré]", + "[Retiré]", + "[Retiré]", + "[Retiré]", + "Lait Lon Lon", + "Coeur", + "Rubis Vert", + "Rubis Bleu", + "Rubis Rouge", + "Rubis Pourpre", + "Énorme Rubis", + "[Retiré]", + "Bâtons Mojo (5)", + "Bâtons Mojo (10)", + "Noix Mojo (5)", + "Noix Mojo (10)", + "Bombes (5)", + "Bombes (10)", + "Bombes (20)", + "Bombes (30)", + "Flèches (Petites)", + "Flèches (Moyennes)", + "Flèches (Grandes)", + "Graines Mojo (30)", + "Missile Teigneux (5)", + "Missile Teigneux (20)", + "Amélioration des Bâtons Mojo (20)", + "Amélioration des Bâtons Mojo (30)", + "Amélioration des Noix Mojo (30)", + "Amélioration des Noix Mojo (40)", +}; + +std::vector itemNamesGer = { + "Deku-Stab", + "Deku-Nuss", + "Bombe", + "Feenbogen", + "Feuerpfeil", + "Dins Feuerinferno", + "Feen-Schleuder", + "Feen-Okarina", + "Okarina der Zeit", + "Krabbelmine", + "Enterhaken", + "Enterhaken (Lang)", + "Eispfeil", + "Farores Donnersturm", + "Bumerang", + "Auge der Wahrheit", + "Zauberbohne", + "Megatonhammer", + "Lichtpfeil", + "Nayrus Umarmung", + "Leere Flasche", + "Roter Trank", + "Grüner Trank", + "Blauer Trank", + "Fee in Flasche", + "Fisch", + "Lon Lon Milch & Flasche", + "Brief von Ruto", + "Blaue Flamme", + "Insekten", + "Großer Irrgeist", + "Lon Lon Milch (Halb)", + "Irrgeist", + "Seltsames Ei", + "Huhn", + "Brief von Zelda", + "Fuchsmaske", + "Totenkopfmaske", + "Schädelmaske", + "Hasenohren", + "Goron-Maske", + "Zora-Maske", + "Gerudo-Maske", + "Maske der Wahrheit", + "AUSVERKAUFT", + "Taschenei", + "Taschenhuhn", + "Cojiro", + "Seltsamer Pilz", + "Seltsamer Trank", + "Säge des Schmugglers", + "Goronen-Schwert (Kaputt)", + "Rezept", + "Augenfrosch", + "Augentropfen", + "Abholschein", + "Feenbogen & Feuerpfeil", + "Feenbogen & Eispfeil", + "Feenbogen & Lichtpfeil", + "Kokiri-Schwert", + "Master-Schwert", + "Riesenmesser & Biggorons Schwert", + "Deku-Schild", + "Hylia-Schild", + "Spiegelschild", + "Kokiri-Gewand", + "Goronen-Gewand", + "Zora-Gewand", + "Kokiri-Stiefel", + "Eisenstiefel", + "Schwebestiefel", + "Kugelbeutel (30)", + "Kugelbeutel (40)", + "Kugelbeutel (50)", + "Köcher (30)", + "Großer Köcher (40)", + "Riesenköcher (50)", + "Bombentasche (20)", + "Große Bombentasche (30)", + "Riesen-Bombentasche (40)", + "Goronen-Armband", + "Silberhandschuhe", + "Goldhandschuhe", + "Silberschuppe", + "Goldschuppe", + "Riesenmesser (Kaputt)", + "Erwachsenenbörse", + "Riesenbörse", + "Deku-Samen (5)", + "Angel", + "Menuett des Waldes", + "Bolero des Feuers", + "Serenade des Wassers", + "Requiem der Geister", + "Nocturne der Schatten", + "Präludium des Lichts", + "Zeldas Wiegenlied", + "Eponas Lied", + "Sarias Lied", + "Sonnenlied", + "Hymne der Zeit", + "Sturm-Lied", + "Amulett des Waldes", + "Amulett des Feuers", + "Amulett des Wassers", + "Amulett der Geister", + "Amulett der Schatten", + "Amulett des Lichts", + "Kokiri-Smaragd", + "Goronen-Rubin", + "Zora-Saphir", + "Stein des Wissens", + "Gerudo-Pass", + "Goldene Skulltula-Marke", + "Herzcontainer", + "Herzteil", + "Boss-Schlüssel", + "Kompass", + "Dungeon-Karte", + "Kleiner Schlüssel", + "Kleine Magie", + "Große Magie", + "Herzteil", + "[Entfernt]", + "[Entfernt]", + "[Entfernt]", + "[Entfernt]", + "[Entfernt]", + "[Entfernt]", + "[Entfernt]", + "Lon Lon Milch", + "Herz", + "Grüner Rubin", + "Blauer Rubin", + "Roter Rubin", + "Violetter Rubin", + "Silberner Rubin", + "[Entfernt]", + "Deku-Stäbe (5)", + "Deku-Stäbe (10)", + "Deku-Nüsse (5)", + "Deku-Nüsse (10)", + "Bomben (5)", + "Bomben (10)", + "Bomben (20)", + "Bomben (30)", + "Pfeile (Klein)", + "Pfeile (Mittel)", + "Pfeile (Groß)", + "Deku-Samen (30)", + "Krabbelmine (5)", + "Krabbelmine (20)", + "Deku-Stab-Erweiterung (20)", + "Deku-Stab-Erweiterung (30)", + "Deku-Nuss-Erweiterung (30)", + "Deku-Nuss-Erweiterung (40)", +}; + +std::vector questItemNamesEng = { "Forest Medallion", "Fire Medallion", "Water Medallion", "Spirit Medallion", "Shadow Medallion", "Light Medallion", "Minuet of Forest", "Bolero of Fire", "Serenade of Water", "Requiem of Spirit", "Nocturne of Shadow", "Prelude of Light", "Zelda's Lullaby", "Epona's Song", "Saria's Song", @@ -288,6 +607,24 @@ std::vector questItemNames = { "Zora's Sapphire", "Stone of Agony", "Gerudo's Card", "Gold Skulltula Token", }; +std::vector questItemNamesFra = { + "Médaillon de la Forêt", "Médaillon du Feu", "Médaillon de l'Eau", "Médaillon de l'Esprit", + "Médaillon de l'Ombre", "Médaillon de la Lumière", "Menuet des Bois", "Boléro du Feu", + "Sérénade de l'Eau", "Requiem de l'Esprit", "Nocturne de l'Ombre", "Prélude de la Lumière", + "Berceuse de Zelda", "Chant d'Epona", "Chant de Saria", "Chant du Soleil", + "Chant du Temps", "Chant des Tempêtes", "Émeraude Kokiri", "Rubis Goron", + "Saphir Zora", "Pierre de Souffrance", "Carte Gerudo", "Symbole de Skulltula d'Or", +}; + +std::vector questItemNamesGer = { + "Amulett des Waldes", "Amulett des Feuers", "Amulett des Wassers", "Amulett der Geister", + "Amulett der Schatten", "Amulett des Lichts", "Menuett des Waldes", "Bolero des Feuers", + "Serenade des Wassers", "Requiem der Geister", "Nocturne der Schatten", "Präludium des Lichts", + "Zeldas Wiegenlied", "Eponas Lied", "Sarias Lied", "Sonnenlied", + "Hymne der Zeit", "Sturm-Lied", "Kokiri-Smaragd", "Goronen-Rubin", + "Zora-Saphir", "Stein des Wissens", "Gerudo-Pass", "Goldene Skulltula-Marke", +}; + std::array rcareaPrefixes = { "KF", "LW", @@ -334,23 +671,52 @@ const std::string& SohUtils::GetSceneName(int32_t scene) { } const std::string& SohUtils::GetItemName(int32_t item) { - if (item > itemNames.size()) { + const std::vector* currentItemNames = nullptr; + + switch (gSaveContext.language) { + case LANGUAGE_FRA: + currentItemNames = &itemNamesFra; + break; + case LANGUAGE_GER: + currentItemNames = &itemNamesGer; + break; + case LANGUAGE_ENG: + default: + currentItemNames = &itemNamesEng; + break; + } + + if (item >= currentItemNames->size()) { SPDLOG_WARN("Passed invalid item id to SohUtils::GetItemName: ({})", item); assert(false); return ""; } - return itemNames[item]; + return (*currentItemNames)[item]; } const std::string& SohUtils::GetQuestItemName(int32_t item) { - if (item > questItemNames.size()) { + const std::vector* currentQuestItemNames = nullptr; + + switch (gSaveContext.language) { + case LANGUAGE_FRA: + currentQuestItemNames = &questItemNamesFra; + break; + case LANGUAGE_GER: + currentQuestItemNames = &questItemNamesGer; + break; + case LANGUAGE_ENG: + default: + currentQuestItemNames = &questItemNamesEng; + break; + } + if (item > questItemNamesEng.size()) { SPDLOG_WARN("Passed invalid quest item id to SohUtils::GetQuestItemName: ({})", item); assert(false); return ""; } - return questItemNames[item]; + return (*currentQuestItemNames)[item]; } const std::string& SohUtils::GetRandomizerCheckAreaPrefix(int32_t rcarea) { From 93c163a99cbc54553ad387e46e2a8324f4edcd96 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:53:56 -0400 Subject: [PATCH 34/98] standardize scrub entrances and matching check --- .../Enhancements/randomizer/ShuffleFairies.cpp | 2 +- .../randomizer/randomizer_entrance_tracker.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index 666ba0a21..420ec0864 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -391,7 +391,7 @@ void Rando::StaticData::RegisterFairyLocations() { locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY)); locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::Fairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY)); locationTable[RC_TH_KITCHEN_SUN_FAIRY] = Location::Fairy(RC_TH_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", RHT_TH_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_SUN_FAIRY)); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::Fairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY)); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::Fairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Deku Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY)); locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::Fairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Royal Family's Tomb Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY)); locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY)); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 1a635f58e..4b3534d36 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -120,10 +120,10 @@ const EntranceData entranceData[] = { { ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods Underwater Shortcut", "Zora's River Underwater Shortcut", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD, "lw"}, { ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, ENTR_LOST_WOODS_NORTH_EXIT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods North Exit", "Sacred Forest Meadow South Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_OVERWORLD, "lw"}, { ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Tunnel Grotto Entry", "LW Tunnel Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest", 1}, - { ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW North Grotto Entry", "LW Scrubs Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW North Grotto Entry", "LW Deku Scrub Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,scrubs", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Meadow Grotto Entry", "Deku Theater", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage", 1}, { ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "LW Tunnel Grotto", "LW Tunnel Grotto Entry", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest"}, - { ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), {{ SCENE_GROTTOS, 0x07 }}, "LW Scrubs Grotto", "LW North Grotto Entry", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), {{ SCENE_GROTTOS, 0x07 }}, "LW Deku Scrub Grotto", "LW North Grotto Entry", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,scrubs"}, { ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), {{ SCENE_GROTTOS, 0x0C }}, "Deku Theater", "LW Meadow Grotto Entry", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage"}, // Sacred Forest Meadow @@ -210,11 +210,11 @@ const EntranceData entranceData[] = { { ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "Death Mountain Crater Upper Exit", "Death Mountain Trail Top Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD}, { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Great Fairy Entry", "DMC Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR, "", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Upper Grotto Entry", "DMC Upper Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Hammer Grotto Entry", "DMC Scrubs Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Hammer Grotto Entry", "DMC Deku Scrub Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, { ENTR_FIRE_TEMPLE_ENTRANCE, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "Death Mountain Crater Outside Temple", "Fire Temple Entrance", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, { ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x01 }}, "DMC Great Fairy Fountain", "DMC Great Fairy Entry", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR}, { ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "DMC Upper Grotto", "DMC Upper Grotto Entry", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "DMC Scrubs Grotto", "DMC Hammer Grotto Entry", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "DMC Deku Scrub Grotto", "DMC Hammer Grotto Entry", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs"}, { ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, ENTR_FIRE_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple Entrance", "Death Mountain Crater Outside Temple", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON}, { ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, ENTR_FIRE_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple Boss Door", "Volvagia", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, { ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE_BOSS), "Volvagia", "Fire Temple Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, @@ -225,15 +225,15 @@ const EntranceData entranceData[] = { { ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, ENTR_GORON_CITY_DARUNIA_ROOM_EXIT, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City Darunia's Room Backdoor", "Death Mountain Crater Bridge Exit", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD, "gc"}, { ENTR_LOST_WOODS_TUNNEL_SHORTCUT, ENTR_GORON_CITY_TUNNEL_SHORTCUT, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City Tunnel Shortcut", "Lost Woods Tunnel Shortcut", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "gc,lw"}, { ENTR_GORON_SHOP_0, ENTR_GORON_CITY_OUTSIDE_SHOP, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Shop Entry", "Goron Shop", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc", 1}, - { ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Lava Grotto Entry", "GC Scrubs Grotto", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Lava Grotto Entry", "GC Deku Scrub Grotto", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs", 1}, { ENTR_GORON_CITY_OUTSIDE_SHOP, ENTR_GORON_SHOP_0, SINGLE_SCENE_INFO(SCENE_GORON_SHOP), "Goron Shop", "GC Shop Entry", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc"}, - { ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "GC Scrubs Grotto", "GC Lava Grotto Entry", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "GC Deku Scrub Grotto", "GC Lava Grotto Entry", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs"}, // Zora's River { ENTR_HYRULE_FIELD_RIVER_EXIT, ENTR_ZORAS_RIVER_WEST_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "Zora's River Lower Exit", "Hyrule Field River Exit", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, { ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "Zora's River Underwater Shortcut", "Lost Woods Underwater Shortcut", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, { ENTR_ZORAS_DOMAIN_ENTRANCE, ENTR_ZORAS_RIVER_WATERFALL_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "Zora's River Waterfall Exit", "Zora's Domain Entrance", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD}, - { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Rock Circle Grotto Entry", "ZR Deku SCrub Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Rock Circle Grotto Entry", "ZR Deku Scrub Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Raised Boulder Grotto Entry", "ZR Fairy Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Raised Open Grotto Entry", "ZR Open Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "chest", 1}, { ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "ZR Deku Scrub Grotto", "ZR Rock Circle Grotto Entry", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs"}, @@ -275,7 +275,7 @@ const EntranceData entranceData[] = { { ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Northwest Boulder Grotto Entry", "HF Fairy Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF West Rock Circle Grotto Entry", "HF Cow Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF South Open Grotto Entry", "HF Open Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Fenced Grotto Entry", "HF Fenced Scrub Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Fenced Grotto Entry", "HF Fenced Deku Scrub Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, { ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Southeast Boulder Grotto Entry", "HF Southeast Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, { ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Near Market Boulder Grotto", "HF Near Market Boulder Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, { ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET), {{ SCENE_GROTTOS, 0x01 }}, "HF Stone Bridge Tree Grotto", "HF Stone Bridge Tree Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "spider"}, @@ -283,7 +283,7 @@ const EntranceData entranceData[] = { { ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "HF Fairy Grotto", "HF Northwest Boulder Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, { ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), {{ SCENE_GROTTOS, 0x05 }}, "HF Cow Grotto", "HF West Rock Circle Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed"}, { ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Open Grotto", "HF South Open Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), {{ SCENE_GROTTOS, 0x02 }}, "HF Fenced Scrub Grotto", "HF Fenced Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "srubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), {{ SCENE_GROTTOS, 0x02 }}, "HF Fenced Deku Scrub Grotto", "HF Fenced Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "scrubs"}, { ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Southeast Grotto", "HF Southeast Boulder Grotto Entry", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, // Lon Lon Ranch From cbd376afa9a14e2804efbb0cfd0e8aa7f98d33e7 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Thu, 28 Aug 2025 08:59:45 -0700 Subject: [PATCH 35/98] Search Tweaks (#5767) * Increase vibrancy of search field color. Set autofocus to only happen on fresh menu load. * Revert tooltip addition. --- soh/soh/SohGui/Menu.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/soh/soh/SohGui/Menu.cpp b/soh/soh/SohGui/Menu.cpp index 5a609a935..98db5d239 100644 --- a/soh/soh/SohGui/Menu.cpp +++ b/soh/soh/SohGui/Menu.cpp @@ -496,6 +496,7 @@ void Menu::Draw() { SyncVisibilityConsoleVariable(); } +static bool freshOpen = true; void Menu::DrawElement() { for (auto& [reason, info] : disabledMap) { info.active = info.evaluation(info); @@ -538,6 +539,7 @@ void Menu::DrawElement() { if (!popout) { ImGui::PopStyleVar(); } + freshOpen = true; ImGui::PopStyleColor(); ImGui::End(); return; @@ -654,13 +656,13 @@ void Menu::DrawElement() { std::string menuSearchText = ""; if (headerSearch) { ImGui::SameLine(); - if (autoFocus && ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !ImGui::IsAnyItemActive() && - !ImGui::IsMouseClicked(0)) { - ImGui::SetKeyboardFocusHere(0); + if (autoFocus && freshOpen) { + ImGui::SetKeyboardFocusHere(); } auto color = UIWidgets::ColorValues.at(menuThemeIndex); - color.w = 0.2f; + color.w = 0.6f; ImGui::PushStyleColor(ImGuiCol_FrameBg, color); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); menuSearch.Draw("##search", 200.0f); menuSearchText = menuSearch.InputBuf; menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '), menuSearchText.end()); @@ -668,6 +670,7 @@ void Menu::DrawElement() { ImGui::SameLine(headerWidth - 200.0f + style.ItemSpacing.x); ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Search..."); } + ImGui::PopStyleVar(); ImGui::PopStyleColor(); } ImGui::EndChild(); @@ -853,6 +856,9 @@ void Menu::DrawElement() { poppedSize = ImGui::GetWindowSize(); poppedPos = ImGui::GetWindowPos(); } + if (freshOpen) { + freshOpen = false; + } ImGui::End(); } } // namespace Ship From 263afb9c09f117bf0e9896decd04bdf6cf26fd94 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 02:21:23 +0200 Subject: [PATCH 36/98] Fixes for the German translation in item_list.cpp --- soh/soh/Enhancements/randomizer/item_list.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 7f22fe83f..dee98c1f8 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -35,10 +35,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_DINS_FIRE] = Item(RG_DINS_FIRE, Text{ "Din's Fire", "Feu de Din", "Dins Feuerinferno" }, ITEMTYPE_ITEM, GI_DINS_FIRE, true, LOGIC_DINS_FIRE, RHT_DINS_FIRE, ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FARORES_WIND] = Item(RG_FARORES_WIND, Text{ "Farore's Wind", "Vent de Farore", "Farores Donnersturm" }, ITEMTYPE_ITEM, GI_FARORES_WIND, true, LOGIC_FARORES_WIND, RHT_FARORES_WIND, ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{ "Nayru's Love", "Amour de Nayru", "Nayrus Umarmung" }, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, LOGIC_NAYRUS_LOVE, RHT_NAYRUS_LOVE, ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo-Pass" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo-Paß" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricots Magiques", "Wundererbse" }, ITEMTYPE_ITEM, GI_BEAN, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN, ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{ "Magic Bean Pack", "Paquet de Haricots Magiques", "Wundererbsen-Packung" }, ITEMTYPE_ITEM, RG_MAGIC_BEAN_PACK, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN_PACK, RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{ "Double Defense", "Double Défence", "Doppelte Verteidigung" }, ITEMTYPE_ITEM, RG_DOUBLE_DEFENSE, true, LOGIC_DOUBLE_DEFENSE, RHT_DOUBLE_DEFENSE, RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); @@ -48,10 +48,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ZELDAS_LETTER] = Item(RG_ZELDAS_LETTER, Text{ "Zelda's Letter", "Lettre de Zelda", "Zeldas Brief" }, ITEMTYPE_ITEM, GI_LETTER_ZELDA, true, LOGIC_ZELDAS_LETTER, RHT_ZELDAS_LETTER, ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POCKET_EGG] = Item(RG_POCKET_EGG, Text{ "Pocket Egg", "Oeuf de poche", "Ei" }, ITEMTYPE_ITEM, GI_POCKET_EGG, true, LOGIC_POCKET_EGG, RHT_POCKET_EGG, ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_COJIRO] = Item(RG_COJIRO, Text{ "Cojiro", "P'tit Poulet", "Henni" }, ITEMTYPE_ITEM, GI_COJIRO, true, LOGIC_COJIRO, RHT_COJIRO, ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champigon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champignon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Modertrank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, LOGIC_ODD_POULTICE, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Säge" }, ITEMTYPE_ITEM, GI_SAW, true, LOGIC_POACHERS_SAW, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbrochenes Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Rezept" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, LOGIC_PRESCRIPTION, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Glotzfrosch" }, ITEMTYPE_ITEM, GI_FROG, true, LOGIC_EYEBALL_FROG, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Augentropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, LOGIC_EYEDROPS, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); @@ -64,7 +64,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Bombentasche (prog.)" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, ITEM_CATEGORY_MAJOR, true); itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Bogen (prog.)" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, ITEM_CATEGORY_MAJOR, true); itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Schleuder (prog.)" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, ITEM_CATEGORY_MAJOR, true); - itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Geldbörse (prog.)" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, true); + itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Börse (prog.)" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, true); itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Zora-Schuppe (prog.)" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, ITEM_CATEGORY_MAJOR, true); itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Nuß-Kapazität (prog.)" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, ITEM_CATEGORY_MAJOR, true); itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Stab-Kapazität (prog.)" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, ITEM_CATEGORY_MAJOR, true); @@ -363,7 +363,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_MAGIC_INF] = Item(RG_MAGIC_INF, Text{ "Infinite Magic Meter", "Magie Infinie", "Unendliche Magische Kraft" }, ITEMTYPE_ITEM, RG_MAGIC_INF, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_INF, RG_MAGIC_INF, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "Missiles Teigneux Infinis", "Unendliche Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_INF, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_INF, RG_BOMBCHU_INF, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_INF].SetCustomDrawFunc(Randomizer_DrawBombchuBag); - itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "Bourse Infinie", "Unendliche Geldbörse" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, LOGIC_PROGRESSIVE_WALLET, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); + itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "Bourse Infinie", "Unendliche Börse" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, LOGIC_PROGRESSIVE_WALLET, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_SKELETON_KEY] = Item(RG_SKELETON_KEY, Text{ "Skeleton Key", "Clé Squelette", "Skelettschlüssel" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_SKELETON_KEY, RHT_SKELETON_KEY, RG_SKELETON_KEY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey); @@ -393,10 +393,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Titanhandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_GOLD, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GOLDEN_GAUNTLETS, ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SILVER_SCALE] = Item(RG_SILVER_SCALE, Text{ "Silver Scale", "Écaille d'argent", "Silberne Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_SILVER_SCALE, ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GOLDEN_SCALE] = Item(RG_GOLDEN_SCALE, Text{ "Golden Scale", "Écaille d'or", "Goldene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_GOLDEN, true, LOGIC_PROGRESSIVE_SCALE, RHT_GOLDEN_SCALE, ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Große Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, LOGIC_PROGRESSIVE_WALLET, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesengeldbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, LOGIC_PROGRESSIVE_WALLET, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Goldene Geldbörse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); - itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Petite Bourse", "Kindergeldbörse" }, ITEMTYPE_ITEM, RG_CHILD_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Große Börse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, LOGIC_PROGRESSIVE_WALLET, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesenbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, LOGIC_PROGRESSIVE_WALLET, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Goldene Börse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); + itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Petite Bourse", "Kinderbörse" }, ITEMTYPE_ITEM, RG_CHILD_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku-Nuß-Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku-Nuß-Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku-Stab-Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); From 3c084ef2a19ea594fe1bbd366a298239f42cc0f6 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:17:35 +0200 Subject: [PATCH 37/98] Fixes for the German translation in item_list.cpp --- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index dee98c1f8..202d2c56c 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -51,7 +51,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champignon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Modertrank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, LOGIC_ODD_POULTICE, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Säge" }, ITEMTYPE_ITEM, GI_SAW, true, LOGIC_POACHERS_SAW, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbrochenes Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Rezept" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, LOGIC_PRESCRIPTION, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Glotzfrosch" }, ITEMTYPE_ITEM, GI_FROG, true, LOGIC_EYEBALL_FROG, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Augentropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, LOGIC_EYEDROPS, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); From 113e899f099e55ae90645ef6dfb42f2053a1df03 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:38:55 +0200 Subject: [PATCH 38/98] Fixes for the German translation in shops.cpp --- .../Enhancements/randomizer/3drando/shops.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 441454cd0..072177673 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -434,12 +434,12 @@ void InitTrickNames() { }; trickNameTable[RG_BROKEN_SWORD] = { Text{ "Broken Biggoron's Sword", "Épée brisée de Grogoron", - "zerbr. Biggoron-Schwert" }, // "Espada de Biggoron rota" - Text{ "Broken Giant's Knife", "Lame des Géants brisée", "zerbr. Langschwert" }, // "Daga gigante rota" - Text{ "Broken Noble Sword", "Épée noble brisée", "zerbr. Edelschwert" }, // "Espada noble rota" - Text{ "Broken Picori Blade", "Épée Minish brisée", "zerbr. Schwert der Minish" }, // "Espada minish rota" + "Zerbr. Biggoron-Schwert" }, // "Espada de Biggoron rota" + Text{ "Broken Giant's Knife", "Lame des Géants brisée", "Zerbr. Langschwert" }, // "Daga gigante rota" + Text{ "Broken Noble Sword", "Épée noble brisée", "Zerbr. Edelschwert" }, // "Espada noble rota" + Text{ "Broken Picori Blade", "Épée Minish brisée", "Zerbr. Schwert der Minish" }, // "Espada minish rota" Text{ "Decayed Master Sword", "Épée de légende pourrie", - "zerfr. Master-Schwert" }, // "Espada decadente de leyenda" + "Zerf. Master-Schwert" }, // "Espada decadente de leyenda" }; trickNameTable[RG_PRESCRIPTION] = { Text{ "Biggoron's Prescription", "Ordonnance de Grogoron", "Biggorons Rezept" }, // "Receta de Biggoron" @@ -772,21 +772,21 @@ void InitTrickNames() { trickNameTable[RG_KOKIRI_EMERALD] = { Text{ "Pendant of Courage", "Pendentif du courage", "Amulett des Mutes" }, // "Colgante del valor" - Text{ "Farore's Pearl", "Perle de Farore", "Farores Deamont" }, // "Orbe de Farore" + Text{ "Farore's Pearl", "Perle de Farore", "Farores Perle" }, // "Orbe de Farore" Text{ "Aquanine", "Smaragdine", "Smaragdstahl" }, // "Yerbánida" Text{ "Farore's Emerald", "Émeraude de Farore", "Farore-Smaragd" }, // "Esmeralda de Farore" Text{ "Kokiri's Peridot", "Péridot Kokiri", "Kokiri-Peridot" }, // "Ágata de los Kokiri" }; trickNameTable[RG_GORON_RUBY] = { Text{ "Pendant of Power", "Pendentif de la force", "Amulett der Stärke" }, // "Colgante del poder" - Text{ "Din's Pearl", "Perle de Din", "Dins Deamont" }, // "Orbe de Din" + Text{ "Din's Pearl", "Perle de Din", "Dins Perle" }, // "Orbe de Din" Text{ "Crimsonine", "Alzanine", "Scharlachstahl" }, // "Bermellina" Text{ "Din's Ruby", "Rubis de Din", "Din-Rubin" }, // "Rubí de Din" Text{ "Goron's Garnet", "Grenat Goron", "Goronen-Granat" }, // "Topacio de los Goron" }; trickNameTable[RG_ZORA_SAPPHIRE] = { Text{ "Pendant of Wisdom", "Pendentif de la sagesse", "Amulett der Weisheit" }, // "Colgante de la sabiduría" - Text{ "Nayru's Pearl", "Perle de Nayru", "Nayrus Deamont" }, // "Orbe de Nayru" + Text{ "Nayru's Pearl", "Perle de Nayru", "Nayrus Perle" }, // "Orbe de Nayru" Text{ "Azurine", "Aquanine", "Azurstahl" }, // "Azurina" Text{ "Nayru's Sapphire", "Saphir de Nayru", "Nayru-Saphir" }, // "Zafiro de Nayru" Text{ "Zora's Aquamarine", "Aquamarine Zora", "Zora-Aquamarin" }, // "Lapislázuli de los Zora" @@ -1169,4 +1169,4 @@ Text GetIceTrapName(uint8_t id) { } // Randomly get the easy, medium, or hard name for the given item id return RandomElement(trickNameTable[id]); -} \ No newline at end of file +} From e0e3cb21a3d71526fce1ca45704617e01c8f42f1 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:41:52 +0200 Subject: [PATCH 39/98] Fixes for the German translation in item_list.cpp --- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 202d2c56c..1544b6a08 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -51,7 +51,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champignon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Modertrank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, LOGIC_ODD_POULTICE, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Säge" }, ITEMTYPE_ITEM, GI_SAW, true, LOGIC_POACHERS_SAW, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Rezept" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, LOGIC_PRESCRIPTION, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Glotzfrosch" }, ITEMTYPE_ITEM, GI_FROG, true, LOGIC_EYEBALL_FROG, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Augentropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, LOGIC_EYEDROPS, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); From 9a59af2a5e600eb98826c2f15ca87100a77c4b5b Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:57:20 +0200 Subject: [PATCH 40/98] Fixes for the German translation in hint_list_item.cpp --- .../randomizer/3drando/hint_list/hint_list_item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index f5195c91d..c74c0ff23 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -426,7 +426,7 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a tree killer", /*german*/"ein Baumtöter", /*french*/"un coupeur d'arbres")}); // /*spanish*/un destructor de árboles - hintTextTable[RHT_BROKEN_SWORD] = HintText(CustomMessage("the Broken Goron's Sword", /*german*/"das zerbrochene Goronen-Schwert", /*french*/"l'Épée Brisée de Goron"), + hintTextTable[RHT_BROKEN_SWORD] = HintText(CustomMessage("the Broken Goron's Sword", /*german*/"das Zerbr. Goronen-Schwert", /*french*/"l'Épée Brisée de Goron"), // /*spanish*/la espada goron rota { CustomMessage("a trade quest item", /*german*/"ein Handelsgegenstand", /*french*/"un objet de quête d'échanges"), From fc866e695e6d641a65d4d30ab7a1e375afc43499 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:09:45 +0200 Subject: [PATCH 41/98] Fixes for the German translation in randomizer.cpp --- soh/soh/Enhancements/randomizer/randomizer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index bbab5ebb3..49f5fa45a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5122,12 +5122,12 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Das ist kein Item - das ist Karma.", "Und wieder hat Dich 'ne Kiste besiegt.", "Rauru lacht Dich aus.", - "Saria hat sich gerade entfreundet.", + "Salia hat sich gerade entfreundet.", "Prinzessin Ruto hat die Verlobung aufgelöst.", "Kein Seed, kein Ärger!", "Diese Truhe wurde Ihnen präsentiert von: ABSICHT!", "Nicht heute.", - "Nächster halt, #Frosthausen#!", + "Nächster Halt, #Frosthausen#!", "Genau so nützlich wie Navi im Bosskampf.", "Zelda? Die kennt Dich nicht.", "Zufall? Nein. Absicht!", @@ -5170,11 +5170,11 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Der Spind von Davy Jones!", "Herzog Onkled lacht Dich aus.", "GEWINNER!", - "vERLIERER!", + "VERLIERER!", "Drücke B, Unten und Select um zu überleben.", "#Chill# mal jetzt.", "Hier halt mal eben.", - "Sony lacht Dich aus", + "Sony lacht Dich aus!", "Dieses Item ist nicht in deinem Land verfügbar.", "Es ist wichtig, die #Kühltruhe# mal für einen Tag auszuschalten.", "#Kacknoob#!", From beea799081062ae846888b48a95d1fa003a187f5 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:38:40 +0200 Subject: [PATCH 42/98] Fixes for the German translation in kaleidoscope_ger.json --- .../accessibility/texts/kaleidoscope_ger.json | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/soh/assets/custom/accessibility/texts/kaleidoscope_ger.json b/soh/assets/custom/accessibility/texts/kaleidoscope_ger.json index f66b82736..95fb567b6 100644 --- a/soh/assets/custom/accessibility/texts/kaleidoscope_ger.json +++ b/soh/assets/custom/accessibility/texts/kaleidoscope_ger.json @@ -47,7 +47,7 @@ "28": "Blaues Feuer", "29": "Käfer", "30": "Nachtschwärmer", - "31": "Milch (1/2)", + "31": "Milch (Halbe Füllung)", "32": "Irrlicht", "33": "Seltsames Ei", "34": "Huhn", @@ -67,7 +67,7 @@ "48": "Schimmelpilz", "49": "Modertrank", "50": "Säge", - "51": "Goronen-Schwert (zerbrochen)", + "51": "Zerbr. Goronen-Schwert", "52": "Rezept", "53": "Glotzfrosch", "54": "Augentropfen", @@ -78,7 +78,7 @@ "59": "Kokiri-Schwert", "60": "Master-Schwert", "61": "Langschwert", - "62": "Deku-schild", + "62": "Deku-Schild", "63": "Hylia-Schild", "64": "Spiegel-Schild", "65": "Kokiri-Rüstung", @@ -99,13 +99,13 @@ "80": "Goronen-Armband", "81": "Krafthandschuh", "82": "Titanhandschuh", - "83": "Silberschuppe", - "84": "Goldschuppe", - "85": "Langschwert (gebrochen)", + "83": "Silberne Schuppe", + "84": "Goldene Schuppe", + "85": "Zerbr. Langschwert", "86": "Große Börse", "87": "Riesenbörse", "88": "Deku-Kerne", - "89": "Angel", + "89": "Angelrute", "90": "Menuett des Waldes", "91": "Bolero des Feuers", "92": "Serenade des Wassers", @@ -117,7 +117,7 @@ "98": "Salias Lied", "99": "Hymne der Sonne", "100": "Hymne der Zeit", - "101": "Song of Storms", + "101": "Hymne des Sturms", "102": "Amulett des Waldes", "103": "Amulett des Feuers", "104": "Amulett des Wassers", @@ -125,7 +125,7 @@ "106": "Amulett des Schattens", "107": "Amulett des Lichts", "108": "Kokiri-Smaragd", - "109": "Goronen-Opal", + "109": "Goronen-Rubin", "110": "Zora-Saphir", "111": "Stein des Wissens", "112": "Gerudo-Paß", @@ -136,8 +136,8 @@ "117": "Kompaß", "118": "Labyrinth-Karte", "119": "Kleiner Schlüssel", - "120": "MAGIE KLEIN", - "121": "MAGIE GROß", + "120": "Kleine Magieflasche", + "121": "Große Magieflasche", "122": "Biggoron-Schwert", "123": "UNGÜLTIG 1", "124": "UNGÜLTIG 2", @@ -154,24 +154,24 @@ "135": "50 Rubine", "136": "200 Rubine", "137": "UNGÜLTIG 8", - "138": "STÄBE 5", - "139": "STÄBE 10", - "140": "NÜSSE 5", - "141": "NÜSSE 10", + "138": "DEKU-STÄBE 5", + "139": "DEKU-STÄBE 10", + "140": "DEKU-NÜSSE 5", + "141": "DEKU-NÜSSE 10", "142": "BOMBEN 5", "143": "BOMBEN 10", "144": "BOMBEN 20", "145": "BOMBEN 30", - "146": "PFEILE KLEIN", - "147": "PFEILE MITTEL", - "148": "PFEILE GROß", - "149": "KERNE 30", + "146": "PFEILE 5", + "147": "PFEILE 10", + "148": "PFEILE 30", + "149": "DEKU-KERNE 30", "150": "KRABBELMINEN 5", "151": "KRABBELMINEN 20", - "152": "STAB UPGRADE 20", - "153": "STAB UPGRADE 30", - "154": "NUß UPGRADE 30", - "155": "NUß UPGRADE 40", + "152": "DEKU-STAB-KAPAZITÄT 20", + "153": "DEKU-STAB-KAPAZITÄT 30", + "154": "DEKU-NUẞ-KAPAZITÄT 30", + "155": "DEKU-NUẞ-KAPAZITÄT 40", "255": "", "256": "Gespensterwüste", "257": "Gerudo-Festung", From a76c1ca9dbe0b16cee3dcc8f1d8bc7c5884f40ae Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:39:11 +0200 Subject: [PATCH 43/98] Fixes for the German translation in filechoose_ger.json --- soh/assets/custom/accessibility/texts/filechoose_ger.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/assets/custom/accessibility/texts/filechoose_ger.json b/soh/assets/custom/accessibility/texts/filechoose_ger.json index 2ad1322fd..b0fd8b899 100644 --- a/soh/assets/custom/accessibility/texts/filechoose_ger.json +++ b/soh/assets/custom/accessibility/texts/filechoose_ger.json @@ -25,5 +25,5 @@ "quest_sel_vanilla": "Quest - Original", "quest_sel_mq": "Quest - Master Quest", "quest_sel_randomizer": "Quest - Randomizer", - "quest_sel_boss_rush": "Quest - Bosse Rush" -} \ No newline at end of file + "quest_sel_boss_rush": "Quest - Boss Rush" +} From 52d452307e0ed5021b85f29d9b268c332d3da86e Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:41:31 +0200 Subject: [PATCH 44/98] Fixes for the German translation in scenes_ger.json --- soh/assets/custom/accessibility/texts/scenes_ger.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/assets/custom/accessibility/texts/scenes_ger.json b/soh/assets/custom/accessibility/texts/scenes_ger.json index a3f7370e0..5f7da173c 100644 --- a/soh/assets/custom/accessibility/texts/scenes_ger.json +++ b/soh/assets/custom/accessibility/texts/scenes_ger.json @@ -9,7 +9,7 @@ "7": "Schattentempel", "8": "Grund des Brunnens", "9": "Eishöhle", - "10": "", // Treppe zu Ganondorfs Verließ (Keine Title-Card) + "10": "", // Treppe zu Ganondorfs Verlies (Keine Title-Card) "11": "Gerudo-Arena", "12": "Diebesversteck", "13": "Ganons Schloß", @@ -22,7 +22,7 @@ "20": "Reitendes Unheil - Phantom-Ganon", "21": "Subterraner Lavadrachoid - Volvagia", "22": "Aquamöbes Wassertentakel - Morpha", - "23": "Höllische Hexenarmada - Killa Ohmaz", + "23": "Höllische Hexenarmada - Twinrova", "24": "Bestialische Schattenmonstrosität - Bongo Bongo", "25": "Großmeister des Bösen - Ganondorf", "26": "", @@ -109,4 +109,4 @@ "107": "", "108": "", // Debug: SRD Raum (Keine Title-Card) "109": "" // Debug: Schatzkisten Teleport (Keine Title-Card) -} \ No newline at end of file +} From bd4e14659993d5b8bf426b5adf986d97370c5ffe Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 19:33:02 +0200 Subject: [PATCH 45/98] Fixes for the German translation in item_list.cpp --- soh/soh/Enhancements/randomizer/item_list.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 1544b6a08..3f6535c83 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -35,9 +35,9 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_DINS_FIRE] = Item(RG_DINS_FIRE, Text{ "Din's Fire", "Feu de Din", "Dins Feuerinferno" }, ITEMTYPE_ITEM, GI_DINS_FIRE, true, LOGIC_DINS_FIRE, RHT_DINS_FIRE, ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FARORES_WIND] = Item(RG_FARORES_WIND, Text{ "Farore's Wind", "Vent de Farore", "Farores Donnersturm" }, ITEMTYPE_ITEM, GI_FARORES_WIND, true, LOGIC_FARORES_WIND, RHT_FARORES_WIND, ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{ "Nayru's Love", "Amour de Nayru", "Nayrus Umarmung" }, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, LOGIC_NAYRUS_LOVE, RHT_NAYRUS_LOVE, ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); - itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeil" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); + itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo-Paß" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricots Magiques", "Wundererbse" }, ITEMTYPE_ITEM, GI_BEAN, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN, ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{ "Magic Bean Pack", "Paquet de Haricots Magiques", "Wundererbsen-Packung" }, ITEMTYPE_ITEM, RG_MAGIC_BEAN_PACK, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN_PACK, RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); From aacb4ad2f7a87cfaa6e49684d915ac9226a84ede Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Fri, 29 Aug 2025 19:43:32 +0200 Subject: [PATCH 46/98] Fixes for the German translation in shops.cpp --- soh/soh/Enhancements/randomizer/3drando/shops.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 072177673..0a6ff6ac9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -691,7 +691,7 @@ void InitTrickNames() { trickNameTable[RG_RUTOS_LETTER] = { Text{ "Bottle with Maggie's Letter", "Flacon avec lettre de Maggy", - "Flasche (Dolores Brief)" }, // "Carta de Dolores" + "Flasche (Dolores' Brief)" }, // "Carta de Dolores" Text{ "Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei", "Flasche (Brief an Kafei)" }, // "Carta para Kafei" Text{ "Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda", @@ -717,7 +717,7 @@ void InitTrickNames() { }; trickNameTable[RG_SARIAS_SONG] = { Text{ "Mido's Song", "La chanson de Mido", "Midos Lied" }, // "La canción de Mido" - Text{ "Kass' Theme", "Le thème de Kass", "Kashiwa Thema" }, // "El tema de Kass" + Text{ "Kass' Theme", "Le thème de Kass", "Kashiwas Thema" }, // "El tema de Kass" Text{ "Tune of Echoes", "Chant des Échos ", "Melodie des Echos" }, // "Melodía del Eco" }; trickNameTable[RG_SUNS_SONG] = { @@ -772,21 +772,21 @@ void InitTrickNames() { trickNameTable[RG_KOKIRI_EMERALD] = { Text{ "Pendant of Courage", "Pendentif du courage", "Amulett des Mutes" }, // "Colgante del valor" - Text{ "Farore's Pearl", "Perle de Farore", "Farores Perle" }, // "Orbe de Farore" + Text{ "Farore's Pearl", "Perle de Farore", "Farores Deamont" }, // "Orbe de Farore" Text{ "Aquanine", "Smaragdine", "Smaragdstahl" }, // "Yerbánida" Text{ "Farore's Emerald", "Émeraude de Farore", "Farore-Smaragd" }, // "Esmeralda de Farore" Text{ "Kokiri's Peridot", "Péridot Kokiri", "Kokiri-Peridot" }, // "Ágata de los Kokiri" }; trickNameTable[RG_GORON_RUBY] = { Text{ "Pendant of Power", "Pendentif de la force", "Amulett der Stärke" }, // "Colgante del poder" - Text{ "Din's Pearl", "Perle de Din", "Dins Perle" }, // "Orbe de Din" + Text{ "Din's Pearl", "Perle de Din", "Dins Deamont" }, // "Orbe de Din" Text{ "Crimsonine", "Alzanine", "Scharlachstahl" }, // "Bermellina" Text{ "Din's Ruby", "Rubis de Din", "Din-Rubin" }, // "Rubí de Din" Text{ "Goron's Garnet", "Grenat Goron", "Goronen-Granat" }, // "Topacio de los Goron" }; trickNameTable[RG_ZORA_SAPPHIRE] = { Text{ "Pendant of Wisdom", "Pendentif de la sagesse", "Amulett der Weisheit" }, // "Colgante de la sabiduría" - Text{ "Nayru's Pearl", "Perle de Nayru", "Nayrus Perle" }, // "Orbe de Nayru" + Text{ "Nayru's Pearl", "Perle de Nayru", "Nayrus Deamont" }, // "Orbe de Nayru" Text{ "Azurine", "Aquanine", "Azurstahl" }, // "Azurina" Text{ "Nayru's Sapphire", "Saphir de Nayru", "Nayru-Saphir" }, // "Zafiro de Nayru" Text{ "Zora's Aquamarine", "Aquamarine Zora", "Zora-Aquamarin" }, // "Lapislázuli de los Zora" @@ -916,7 +916,7 @@ void InitTrickNames() { }; trickNameTable[RG_MORPHA_SOUL] = { Text{ "Dihydrogen Monoxide", "Monoxyde de Dihydrogène", "Dihydrogenmonoxid" }, - Text{ "Morpha Molecules", "Molécule de Morpha", "Morphas Molekyle" }, + Text{ "Morpha Molecules", "Molécule de Morpha", "Morphas Moleküle" }, Text{ "Wet Stuff", "Truc Mouillé", "nasses Zeug" }, }; trickNameTable[RG_BONGO_BONGO_SOUL] = { @@ -1114,7 +1114,7 @@ void InitTrickNames() { }; trickNameTable[GI_CUCCO] = { Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Improvisierter Wecker"}, // "Alarma emplumada" - Text{"Kakariko Cucco", "Cocotte Cocorico", "Kakariko Huhn" }, // "Cuco de Kakariko" + Text{"Kakariko Cucco", "Cocotte Cocorico", "Kakariko-Huhn" }, // "Cuco de Kakariko" Text{"Hatched Cucco", "Cocotte éclose", "Geschlüpftes Küken" }, // "Pollo" }; trickNameTable[GI_MASK_KEATON] = { From e9f129678153c9ea7059b103d1a74d552e03c815 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Wed, 3 Sep 2025 14:48:46 -0400 Subject: [PATCH 47/98] add scene check to hook and custom message --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 2 +- soh/soh/OTRGlobals.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bf2722f80..ed20eaf7c 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1445,7 +1445,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_GERUDO_GUARD_SET_ACTION_AFTER_TALK: - if (gPlayState->msgCtx.choiceIndex == 0) { + if (gPlayState->msgCtx.choiceIndex == 0 && gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS) { EnGe2* enGe2 = va_arg(args, EnGe2*); EnGe2_SetupCapturePlayer(enGe2, gPlayState); *should = false; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 7d2194cca..5fefe3003 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2510,7 +2510,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if (textId == TEXT_BIG_POE_COLLECTED_RANDO) { messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_AUTO_FORMAT); - } else if (textId == TEXT_GERUDO_GUARD_FRIENDLY && player->talkActor->id == ACTOR_EN_GE2) { + } else if (textId == TEXT_GERUDO_GUARD_FRIENDLY && player->talkActor->id == ACTOR_EN_GE2 && + gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS) { // TODO_TRANSLATE Translate into french and german messageEntry = CustomMessage("Want me to throw you in jail?&\x1B#Yes please&No thanks#", { QM_GREEN }); messageEntry.AutoFormat(); From 405fc7a31dab081d0169001d253794298025f4d4 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Tue, 9 Sep 2025 05:44:19 +0200 Subject: [PATCH 48/98] Fixes for the German translation in util.cpp (#5768) * Fixes for the German translation in util.cpp * Fixes for the German translation in item_list.cpp * Fixes for the German translation in item_list.cpp * Fixes for the German translation in util.cpp * Revert the fixes for the German translation in item_list.cpp * Fixes for the German translation in util.cpp * Fixes for the German translation in util.cpp * Fixes for the German translation in util.cpp * Fixes for the German translation in util.cpp * Fixes for the German translation in util.cpp * Fixes for the German translation in kaleidoscope_ger.json * Revert the fixes for the German translation in kaleidoscope_ger.json * Fixes for the German translation in util.cpp --- soh/soh/util.cpp | 188 ++++++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 85 deletions(-) diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index bd551f937..45e59d14e 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -442,79 +442,79 @@ std::vector itemNamesFra = { std::vector itemNamesGer = { "Deku-Stab", - "Deku-Nuss", + "Deku-Nuß", "Bombe", - "Feenbogen", - "Feuerpfeil", + "Feen-Bogen", + "Feuer-Pfeil", "Dins Feuerinferno", "Feen-Schleuder", "Feen-Okarina", "Okarina der Zeit", "Krabbelmine", + "Fanghaken", "Enterhaken", - "Enterhaken (Lang)", - "Eispfeil", + "Eis-Pfeil", "Farores Donnersturm", "Bumerang", "Auge der Wahrheit", - "Zauberbohne", - "Megatonhammer", - "Lichtpfeil", + "Wundererbse", + "Stahlhammer", + "Licht-Pfeil", "Nayrus Umarmung", "Leere Flasche", - "Roter Trank", - "Grüner Trank", - "Blauer Trank", - "Fee in Flasche", + "Rotes Elixier", + "Grünes Elixier", + "Blaues Elixier", + "Flasche (Fee)", "Fisch", - "Lon Lon Milch & Flasche", - "Brief von Ruto", - "Blaue Flamme", - "Insekten", - "Großer Irrgeist", - "Lon Lon Milch (Halb)", - "Irrgeist", + "Flasche (Milch)", + "Rutos Brief", + "Blaues Feuer", + "Käfer", + "Nachtschwärmer", + "Lon Lon-Milch (Halbe Füllung)", + "Irrlicht", "Seltsames Ei", "Huhn", - "Brief von Zelda", - "Fuchsmaske", - "Totenkopfmaske", - "Schädelmaske", + "Zeldas Brief", + "Fuchs-Maske", + "Geister-Maske", + "Schädel-Maske", "Hasenohren", - "Goron-Maske", + "Goronen-Maske", "Zora-Maske", "Gerudo-Maske", - "Maske der Wahrheit", + "Maske des Wissens", "AUSVERKAUFT", - "Taschenei", - "Taschenhuhn", - "Cojiro", - "Seltsamer Pilz", - "Seltsamer Trank", - "Säge des Schmugglers", - "Goronen-Schwert (Kaputt)", + "Ei", + "Kiki", + "Henni", + "Schimmelpilz", + "Modertrank", + "Säge", + "Zerbr. Goronen-Schwert", "Rezept", - "Augenfrosch", + "Glotzfrosch", "Augentropfen", - "Abholschein", - "Feenbogen & Feuerpfeil", - "Feenbogen & Eispfeil", - "Feenbogen & Lichtpfeil", + "Zertifikat", + "Feen-Bogen & Feuer-Pfeil", + "Feen-Bogen & Eis-Pfeil", + "Feen-Bogen & Licht-Pfeil", "Kokiri-Schwert", "Master-Schwert", - "Riesenmesser & Biggorons Schwert", + "Langschwert & Biggoron-Schwert", "Deku-Schild", "Hylia-Schild", - "Spiegelschild", - "Kokiri-Gewand", - "Goronen-Gewand", - "Zora-Gewand", - "Kokiri-Stiefel", + "Spiegel-Schild", + "Kokiri-Rüstung", + "Goronen-Rüstung", + "Zora-Rüstung", + "Lederstiefel", "Eisenstiefel", - "Schwebestiefel", - "Kugelbeutel (30)", - "Kugelbeutel (40)", - "Kugelbeutel (50)", + "Gleitstiefel", + "Munitionstasche (30)", + "Große Munitionstasche (40)", + "Riesen-Munitionstasche (50)", "Köcher (30)", "Großer Köcher (40)", "Riesenköcher (50)", @@ -522,47 +522,47 @@ std::vector itemNamesGer = { "Große Bombentasche (30)", "Riesen-Bombentasche (40)", "Goronen-Armband", - "Silberhandschuhe", - "Goldhandschuhe", - "Silberschuppe", - "Goldschuppe", - "Riesenmesser (Kaputt)", - "Erwachsenenbörse", + "Krafthandschuhe", + "Titanhandschuhe", + "Silberne Schuppe", + "Goldene Schuppe", + "Zerbr. Langschwert", + "Große Börse", "Riesenbörse", - "Deku-Samen (5)", - "Angel", + "Deku-Kerne (5)", + "Angelrute", "Menuett des Waldes", "Bolero des Feuers", "Serenade des Wassers", "Requiem der Geister", - "Nocturne der Schatten", - "Präludium des Lichts", + "Nocturne des Schattens", + "Kantate des Lichts", "Zeldas Wiegenlied", "Eponas Lied", - "Sarias Lied", - "Sonnenlied", + "Salias Lied", + "Hymne der Sonne", "Hymne der Zeit", - "Sturm-Lied", + "Hymne des Sturms", "Amulett des Waldes", "Amulett des Feuers", "Amulett des Wassers", "Amulett der Geister", - "Amulett der Schatten", + "Amulett des Schattens", "Amulett des Lichts", "Kokiri-Smaragd", "Goronen-Rubin", "Zora-Saphir", "Stein des Wissens", - "Gerudo-Pass", - "Goldene Skulltula-Marke", + "Gerudo-Paß", + "Skulltula-Symbol", "Herzcontainer", "Herzteil", - "Boss-Schlüssel", - "Kompass", - "Dungeon-Karte", + "Master-Schlüssel", + "Kompaß", + "Labyrinth-Karte", "Kleiner Schlüssel", - "Kleine Magie", - "Große Magie", + "Kleine Magieflasche", + "Große Magieflasche", "Herzteil", "[Entfernt]", "[Entfernt]", @@ -571,7 +571,7 @@ std::vector itemNamesGer = { "[Entfernt]", "[Entfernt]", "[Entfernt]", - "Lon Lon Milch", + "Lon Lon-Milch", "Herz", "Grüner Rubin", "Blauer Rubin", @@ -587,16 +587,16 @@ std::vector itemNamesGer = { "Bomben (10)", "Bomben (20)", "Bomben (30)", - "Pfeile (Klein)", - "Pfeile (Mittel)", - "Pfeile (Groß)", - "Deku-Samen (30)", - "Krabbelmine (5)", - "Krabbelmine (20)", - "Deku-Stab-Erweiterung (20)", - "Deku-Stab-Erweiterung (30)", - "Deku-Nuss-Erweiterung (30)", - "Deku-Nuss-Erweiterung (40)", + "Pfeile (5)", + "Pfeile (10)", + "Pfeile (30)", + "Deku-Kerne (30)", + "Krabbelminen (5)", + "Krabbelminen (20)", + "Deku-Stab-Kapazität (20)", + "Deku-Stab-Kapazität (30)", + "Deku-Nuß-Kapazität (30)", + "Deku-Nuß-Kapazität (40)", }; std::vector questItemNamesEng = { @@ -617,12 +617,30 @@ std::vector questItemNamesFra = { }; std::vector questItemNamesGer = { - "Amulett des Waldes", "Amulett des Feuers", "Amulett des Wassers", "Amulett der Geister", - "Amulett der Schatten", "Amulett des Lichts", "Menuett des Waldes", "Bolero des Feuers", - "Serenade des Wassers", "Requiem der Geister", "Nocturne der Schatten", "Präludium des Lichts", - "Zeldas Wiegenlied", "Eponas Lied", "Sarias Lied", "Sonnenlied", - "Hymne der Zeit", "Sturm-Lied", "Kokiri-Smaragd", "Goronen-Rubin", - "Zora-Saphir", "Stein des Wissens", "Gerudo-Pass", "Goldene Skulltula-Marke", + "Amulett des Waldes", + "Amulett des Feuers", + "Amulett des Wassers", + "Amulett der Geister", + "Amulett des Schattens", + "Amulett des Lichts", + "Menuett des Waldes", + "Bolero des Feuers", + "Serenade des Wassers", + "Requiem der Geister", + "Nocturne des Schattens", + "Kantate des Lichts", + "Zeldas Wiegenlied", + "Eponas Lied", + "Salias Lied", + "Hymne der Sonne", + "Hymne der Zeit", + "Hymne des Sturms", + "Kokiri-Smaragd", + "Goronen-Rubin", + "Zora-Saphir", + "Stein des Wissens", + "Gerudo-Paß", + "Goldenes Skulltula-Symbol", }; std::array rcareaPrefixes = { From 837f497ea66e5d841f97aebdf3414ca38785effe Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 8 Sep 2025 20:44:27 -0700 Subject: [PATCH 49/98] Encapsulate `BeginTable` for item and check tracker settings windows. (#5778) --- .../randomizer/randomizer_check_tracker.cpp | 2 +- .../randomizer/randomizer_item_tracker.cpp | 439 +++++++++--------- 2 files changed, 221 insertions(+), 220 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d1ec624ef..81e1c09f0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -2199,8 +2199,8 @@ void CheckTrackerSettingsWindow::DrawElement() { "Checks that you saved the game while having collected.", THEME_COLOR); ImGui::PopStyleVar(1); + ImGui::EndTable(); } - ImGui::EndTable(); } void CheckTrackerWindow::InitElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 5996fea1f..aea0a75d1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -1713,245 +1713,156 @@ static std::unordered_map minimalDisplayTypes = { void ItemTrackerSettingsWindow::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); - ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV); - ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Section settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableHeadersRow(); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true, - ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR); + if (ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Section settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); + CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true, + ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR); - ImGui::PopItemWidth(); - if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, - ComboboxOptions() - .DefaultIndex(TRACKER_WINDOW_FLOATING) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) { - if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), - CheckboxOptions().Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, + ImGui::PopItemWidth(); + if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, ComboboxOptions() - .DefaultIndex(TRACKER_DISPLAY_ALWAYS) + .DefaultIndex(TRACKER_WINDOW_FLOATING) .ComponentAlignment(ComponentAlignments::Right) .LabelPosition(LabelPositions::Far) .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == - TRACKER_DISPLAY_COMBO_BUTTON) { - if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, + + if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) { + if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), + CheckboxOptions().Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, ComboboxOptions() - .DefaultIndex(TRACKER_COMBO_BUTTON_L) + .DefaultIndex(TRACKER_DISPLAY_ALWAYS) .ComponentAlignment(ComponentAlignments::Right) .LabelPosition(LabelPositions::Far) .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, - ComboboxOptions() - .DefaultIndex(TRACKER_COMBO_BUTTON_R) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_COMBO_BUTTON) { + if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, + ComboboxOptions() + .DefaultIndex(TRACKER_COMBO_BUTTON_L) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, + ComboboxOptions() + .DefaultIndex(TRACKER_COMBO_BUTTON_R) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + } + } + ImGui::Separator(); + CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"), + IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR)); + CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"), + IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR)); + CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"), + IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR)); + + ImGui::NewLine(); + CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, + ComboboxOptions() + .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what the numbers under each item are tracking." + "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); + if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == + ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || + CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == + ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) { + if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"), + CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - } - ImGui::Separator(); - CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"), - IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR)); - CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"), - IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR)); - CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"), - IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR)); - ImGui::NewLine(); - CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, - ComboboxOptions() - .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what the numbers under each item are tracking." - "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); - if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == - ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || - CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == - ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) { - if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"), - CheckboxOptions().Color(THEME_COLOR))) { + CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, + ComboboxOptions() + .DefaultIndex(KEYS_COLLECTED_MAX) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what numbers are shown for key tracking.")); + + CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), + itemTrackerTriforcePieceTrackOptions, + ComboboxOptions() + .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what numbers are shown for triforce piece tracking.")); + + ImGui::TableNextColumn(); + + if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - } - - CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, - ComboboxOptions() - .DefaultIndex(KEYS_COLLECTED_MAX) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for key tracking.")); - - CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), - itemTrackerTriforcePieceTrackOptions, - ComboboxOptions() - .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for triforce piece tracking.")); - - ImGui::TableNextColumn(); - - if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == - SECTION_DISPLAY_SEPARATE) { - if (CVarCheckbox("Circle display", CVAR_TRACKER_ITEM("DungeonRewardsLayout"), - CheckboxOptions().DefaultValue(false).Color(THEME_COLOR))) { + if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - } - if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != - SECTION_DISPLAY_HIDDEN) { - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == + if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { - if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"), - CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + if (CVarCheckbox("Circle display", CVAR_TRACKER_ITEM("DungeonRewardsLayout"), + CheckboxOptions().DefaultValue(false).Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"), - CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - } - if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || - (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING && - CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) != - TRACKER_DISPLAY_COMBO_BUTTON)) { - if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, + if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, ComboboxOptions() .DefaultIndex(SECTION_DISPLAY_HIDDEN) .ComponentAlignment(ComponentAlignments::Right) @@ -1959,14 +1870,104 @@ void ItemTrackerSettingsWindow::DrawElement() { .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - } - CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"), - CheckboxOptions() - .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.") - .Color(THEME_COLOR)); + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != + SECTION_DISPLAY_HIDDEN) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { + if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"), + CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + } + if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"), + CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + } + if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } - ImGui::PopStyleVar(1); - ImGui::EndTable(); + if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + + if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || + (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING && + CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) != + TRACKER_DISPLAY_COMBO_BUTTON)) { + if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { + shouldUpdateVectors = true; + } + } + CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"), + CheckboxOptions() + .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.") + .Color(THEME_COLOR)); + + ImGui::PopStyleVar(1); + ImGui::EndTable(); + } } void ItemTrackerWindow::InitElement() { From 27f2292f9d1c3342f2afbafacfe1761b13cfdfa9 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Tue, 9 Sep 2025 04:44:36 +0100 Subject: [PATCH 50/98] Fix gerudo card generation failures (#5774) * quick fix gerudo card * submodules pls --- soh/soh/Enhancements/randomizer/3drando/item_pool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index fb2ac94cc..2a2c294a5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -861,7 +861,7 @@ void GenerateItemPool() { AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); + AddItemToPool(ItemPool, RG_GERUDO_MEMBERSHIP_CARD); ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_ICE_TRAP, false, true); } else { ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, false, true); From ac93d7cc151e2e7c53b312b53e3938ecd9a014b8 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Mon, 8 Sep 2025 23:44:45 -0400 Subject: [PATCH 51/98] Add additional glitch-aiding cutscenes for MQ (#5769) * add mq jabu chest + mq spirit switch cs * update tooltip --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 14 ++++++++++++-- soh/soh/SohGui/SohMenuEnhancements.cpp | 9 +++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 4af24ad19..90b3ff084 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -301,7 +301,8 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li switch (actor->id) { case ACTOR_OBJ_SWITCH: { if (((actor->params == 8224 && gPlayState->sceneNum == SCENE_DODONGOS_CAVERN) || - (actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE)) && + (actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) || + (actor->params == 8961 && gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE)) && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { break; } @@ -340,6 +341,16 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li *should = false; break; } + case ACTOR_EN_BOX: { + if (actor->params == -30457 && gPlayState->sceneNum == SCENE_JABU_JABU && + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { + break; + } + EnBox* boxActor = (EnBox*)actor; + *should = false; + RateLimitedSuccessChime(); + break; + } case ACTOR_BG_HIDAN_FWBIG: case ACTOR_EN_EX_ITEM: case ACTOR_EN_DNT_NOMAL: @@ -352,7 +363,6 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case ACTOR_DOOR_SHUTTER: case ACTOR_BG_ICE_SHUTTER: case ACTOR_OBJ_LIGHTSWITCH: - case ACTOR_EN_BOX: case ACTOR_OBJ_SYOKUDAI: case ACTOR_OBJ_TIMEBLOCK: case ACTOR_EN_PO_SISTERS: diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 41cbbd904..449978240 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -347,10 +347,11 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().DefaultValue(IS_RANDO)); AddWidget(path, "Exclude Glitch-Aiding Cutscenes", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding")) - .Options(CheckboxOptions().Tooltip( - "Don't skip cutscenes that are associated with useful glitches. Currently, it is " - "only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, Dodongo Boss " - "Door Switch CS, Water Temple Dragon Switch CS, and the Box Skip One Point in Jabu.")); + .Options( + CheckboxOptions().Tooltip("Don't skip cutscenes that are associated with useful glitches. Currently, it is " + "only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, Dodongo Boss " + "Door Switch CS, Water Temple Dragon Switch CS, the Box Skip One Point in Jabu, " + "Early Hammer Switch CS in MQ Spirit, and Cow Switch Chest CS in MQ Jabu.")); AddWidget(path, "Text", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Skip Bottle Pickup Messages", WIDGET_CVAR_CHECKBOX) From e5d0f7befa28c2ed3ca07c379661922105c8c932 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 10 Sep 2025 09:10:51 -0700 Subject: [PATCH 52/98] Fix conflict resolution for SkipBlueWarp's VB_GIVE_ITEM_FROM_BLUE_WARP. --- .../SkipCutscene/Story/SkipBlueWarp.cpp | 132 ++---------------- 1 file changed, 10 insertions(+), 122 deletions(-) diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index eed0ac025..83e459fab 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -16,127 +16,6 @@ extern "C" { extern "C" PlayState* gPlayState; static bool sEnteredBlueWarp = false; -/** - * This will override the transitions into the blue warp cutscenes, set any appropriate flags, and - * set the entrance index to where you would normally end up after the blue warp cutscene. This - * should also account for the difference between your first and following visits to the blue warp. - */ -void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { - // Do nothing when in a boss rush - if (IS_BOSS_RUSH) { - return; - } - - bool overrideBlueWarpDestinations = - IS_RANDO && (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); - - // Force blue warp skip on when ER needs to place Link somewhere else. - // This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after. - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) { - bool isBlueWarpCutscene = false; - // Deku Tree Blue warp - if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { - gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP; - isBlueWarpCutscene = true; - // Dodongo's Cavern Blue warp - } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && - gSaveContext.cutsceneIndex == 0xFFF1) { - gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP; - isBlueWarpCutscene = true; - // Jabu Jabu's Blue warp - } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && - gSaveContext.cutsceneIndex == 0xFFF0) { - gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; - isBlueWarpCutscene = true; - // Forest Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && - gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { - // Normally set in the blue warp cutscene - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); - - if (IS_RANDO) { - gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP; - } else { - gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12; - } - - isBlueWarpCutscene = true; - // Fire Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && - gSaveContext.cutsceneIndex == 0xFFF3) { - // Normally set in the blue warp cutscene - Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); - - gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; - isBlueWarpCutscene = true; - // Water Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && - gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { - // Normally set in the blue warp cutscene - gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800; - Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); - - gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP; - isBlueWarpCutscene = true; - // Spirit Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && - gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) { - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; - isBlueWarpCutscene = true; - // Shadow Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && - gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) { - gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; - isBlueWarpCutscene = true; - } - - if (isBlueWarpCutscene) { - if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP) { - // Normally set in the blue warp cutscene - gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; - } - - *should = false; - gSaveContext.cutsceneIndex = 0; - } - - // This is outside the above condition because we want to handle both first and following visits to the blue - // warp - if (sEnteredBlueWarp && overrideBlueWarpDestinations) { - Entrance_OverrideBlueWarp(); - } - } - - sEnteredBlueWarp = false; -} - -/** - * Using this hook to simply observe that Link has entered a bluewarp - * This way we know to allow entrance rando overrides to be processed on the next tranisition hook - */ -void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { - sEnteredBlueWarp = true; -} - -/** - * While we could rely on the Item_Give that's normally called, it's not very clear to the player that they - * received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given - * to the player instead. - */ -void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) { - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { - if (IS_VANILLA) { - if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { - TimeSaverQueueItem(RG_SHADOW_MEDALLION); - } else if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { - TimeSaverQueueItem(RG_SPIRIT_MEDALLION); - } - } - *should = false; - } -} - // Todo: Move item queueing here /** @@ -188,7 +67,16 @@ void RegisterSkipBlueWarp() { * to the player instead. */ COND_VB_SHOULD(VB_GIVE_ITEM_FROM_BLUE_WARP, - CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { *should = false; }); + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { + if (IS_VANILLA) { + if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) { + TimeSaverQueueItem(RG_SHADOW_MEDALLION); + } else if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) { + TimeSaverQueueItem(RG_SPIRIT_MEDALLION); + } + } + *should = false; + }); } void RegisterShouldPlayBlueWarp() { From e6663a1c49d01443c106b50c44f731f499f19beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 17 Sep 2025 00:52:47 +0000 Subject: [PATCH 53/98] entrance shuffle: sign hints (#5335) * entrance shuffle: sign hints * update entrance tracker with hint * show sign hints when any entrances shuffled * only hint when entrance shuffled * avoid crash when loading rando file * fix kf exit * correct hint from sign outside kokiri forest * 3 signs on DMT * improve naming --- .../custom-message/CustomMessageTypes.h | 33 ++++ .../Enhancements/randomizer/3drando/fill.cpp | 1 - .../randomizer/randomizer_check_tracker.cpp | 1 + .../randomizer_entrance_tracker.cpp | 6 +- .../randomizer/randomizer_grotto.c | 2 +- soh/soh/OTRGlobals.cpp | 147 +++++++++++++++++- soh/src/code/z_message_PAL.c | 1 - 7 files changed, 184 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index b5bc0fd6e..635fbcd7d 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -79,8 +79,41 @@ typedef enum { TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x01B3, // 0x1yy for Navi msg range TEXT_MASK_SHOP_SIGN = 0x0207, + TEXT_WATERFALL = 0x022D, TEXT_FROGS_UNDERWATER = 0x022E, + TEXT_OUTSIDE_FISHING_POND = 0x023A, + TEXT_HF_SIGN = 0x0301, + TEXT_HC_GREAT_FAIRY_SIGN = 0x0304, + TEXT_DMT_KAK_SIGN = 0x0305, + TEXT_KAK_TO_GY_SIGN = 0x0306, + TEXT_KAK_WELL_SIGN = 0x0307, + TEXT_KAK_DMT_SIGN = 0x0308, + TEXT_DMT_SIGN = 0x309, + TEXT_DMT_DC_SIGN = 0x030A, + TEXT_GC_SIGN = 0x030B, + TEXT_HF_ZR_SIGN = 0x030C, + TEXT_ZD_SIGN = 0x030E, + TEXT_ZF_JABU_SIGN = 0x030F, + TEXT_KF_LW_SIGN = 0x0314, + TEXT_HF_LON_LON_SIGN = 0x0315, + TEXT_LA_SIGN = 0x0317, + TEXT_LA_LAB_SIGN = 0x0318, + TEXT_GV_SIGN = 0x0319, TEXT_GF_HBA_SIGN = 0x031A, + TEXT_KF_SHOP_SIGN = 0x031E, + TEXT_LINKS_HOUSE_SIGN = 0x031F, + TEXT_KOKIRI_EXIT_SIGN = 0x0320, + TEXT_DMT_GC_SIGN = 0x0321, + TEXT_DMT_DMC_SIGN = 0x0323, + TEXT_DMT_SUMMIT_SIGN = 0x032D, + TEXT_ZD_SHOP_SIGN = 0x0333, + TEXT_OUTSIDE_KOKIRI_SIGN = 0x0339, + TEXT_OUTSIDE_MARKET_SIGN = 0x033A, + TEXT_MIDO_HOUSE_SIGN = 0x033C, + TEXT_KNOW_IT_ALL_HOUSE_SIGN = 0x033D, + TEXT_TWINS_HOUSE_SIGN = 0x033E, + TEXT_SARIAS_HOUSE_SIGN = 0x033F, + TEXT_NO_DIVING_SIGN = 0x0342, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x0346, // 0x3yy for cuttable sign range TEXT_WARP_MINUET_OF_FOREST = 0x088D, TEXT_WARP_BOLERO_OF_FIRE = 0x088E, diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index c53a1477e..fe0ab514b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -9,7 +9,6 @@ #include "hints.hpp" #include "shops.hpp" #include "pool_functions.hpp" -//#include "debug.hpp" #include "soh/Enhancements/randomizer/static_data.h" #include "soh/Enhancements/debugger/performanceTimer.h" diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index c6a70ddf0..52611b89b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -2017,6 +2017,7 @@ void RecalculateAvailableChecks(RandomizerRegion startingRegion /* = RR_ROOT */) StartPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS); const auto& ctx = Rando::Context::GetInstance(); + logic = ctx->GetLogic(); std::vector targetLocations; targetLocations.reserve(RC_MAX); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 4b3534d36..b5dd3e4fa 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -739,7 +739,7 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); UIWidgets::CVarCheckbox( "Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), - UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Tooltip("Reveal the source for undiscovered entrances").Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), UIWidgets::CheckboxOptions() .Tooltip("Reveal the destination for undiscovered entrances") @@ -836,7 +836,7 @@ void EntranceTrackerWindow::DrawElement() { ImGui::BeginChild("ChildEntranceTrackerLocations", ImVec2(0, -8)); bool showTo = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0); bool showFrom = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0); - bool collapsUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); + bool collapseUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); bool highlightPrevious = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0); bool highlightAvailable = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0); bool hideReverse = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1); @@ -892,7 +892,7 @@ void EntranceTrackerWindow::DrawElement() { const char* rplcDstName = showOverride ? override->destination.c_str() : ""; // Filter for entrances by group name, type, source/destination names, and meta tags - if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapsUndiscovered)) || + if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapseUndiscovered)) || ((showOriginal && (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.c b/soh/soh/Enhancements/randomizer/randomizer_grotto.c index 042efadf4..96105728a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_grotto.c +++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.c @@ -184,7 +184,7 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { } // Translates and overrides the passed in entrance index if it corresponds to a -// special grotto entrance (grotto load or returnpoint) and updates player respawn data correctly. +// special grotto entrance (grotto load or return point) and updates player respawn data correctly. s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { // Don't change anything unless grotto shuffle has been enabled diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 04cde6d25..f35fcaaf1 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -26,6 +26,8 @@ #include "Enhancements/audio/AudioCollection.h" #include "Enhancements/enhancementTypes.h" #include "Enhancements/debugconsole.h" +#include "Enhancements/randomizer/entrance.h" +#include "Enhancements/randomizer/location_access.h" #include "Enhancements/randomizer/randomizer.h" #include "Enhancements/randomizer/randomizer_entrance_tracker.h" #include "Enhancements/randomizer/randomizer_item_tracker.h" @@ -2257,6 +2259,149 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { s16 actorParams = 0; if (IS_RANDO) { auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + s16 entrance = -1; + switch (textId) { + case TEXT_WATERFALL: + entrance = ENTR_ZORAS_DOMAIN_ENTRANCE; + break; + case TEXT_OUTSIDE_FISHING_POND: + entrance = ENTR_FISHING_POND_0; + break; + case TEXT_HF_SIGN: + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { + entrance = ENTR_HYRULE_FIELD_STAIRS_EXIT; + } else if (gPlayState->sceneNum == SCENE_GERUDO_VALLEY) { + entrance = ENTR_HYRULE_FIELD_ROCKY_PATH; + } else if (gPlayState->sceneNum == SCENE_LAKE_HYLIA) { + entrance = ENTR_HYRULE_FIELD_FENCE_EXIT; + } + break; + case TEXT_HC_GREAT_FAIRY_SIGN: + entrance = ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC; + break; + case TEXT_DMT_KAK_SIGN: + if (gPlayState->sceneNum == SCENE_HYRULE_FIELD) { + entrance = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; + } else { + entrance = ENTR_KAKARIKO_VILLAGE_GUARD_GATE; + } + break; + case TEXT_KAK_TO_GY_SIGN: + entrance = ENTR_GRAVEYARD_ENTRANCE; + break; + case TEXT_KAK_WELL_SIGN: + entrance = ENTR_BOTTOM_OF_THE_WELL_ENTRANCE; + break; + case TEXT_KAK_DMT_SIGN: + entrance = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; + break; + case TEXT_DMT_SIGN: + entrance = ENTR_GROTTOS_13; + break; + case TEXT_DMT_DC_SIGN: + entrance = ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN; + break; + case TEXT_DMT_GC_SIGN: + entrance = ENTR_GORON_CITY_UPPER_EXIT; + break; + case TEXT_GC_SIGN: + if (gPlayState->sceneNum == SCENE_DEATH_MOUNTAIN_TRAIL) { + entrance = ENTR_GORON_CITY_UPPER_EXIT; + } else { + entrance = ENTR_GORON_CITY_DARUNIA_ROOM_EXIT; + } + break; + case TEXT_DMT_DMC_SIGN: + entrance = ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT; + break; + case TEXT_DMT_SUMMIT_SIGN: + entrance = ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT; + break; + case TEXT_HF_ZR_SIGN: + entrance = ENTR_ZORAS_RIVER_WEST_EXIT; + break; + case TEXT_KF_SHOP_SIGN: + entrance = ENTR_KOKIRI_SHOP_0; + break; + case TEXT_LINKS_HOUSE_SIGN: + entrance = ENTR_LINKS_HOUSE_1; + break; + case TEXT_KOKIRI_EXIT_SIGN: + entrance = ENTR_LOST_WOODS_BRIDGE_EAST_EXIT; + break; + case TEXT_ZD_SIGN: + if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN) { + entrance = ENTR_ZORAS_RIVER_WATERFALL_EXIT; + } else { + entrance = ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT; + } + break; + case TEXT_ZF_JABU_SIGN: + entrance = ENTR_JABU_JABU_ENTRANCE; + break; + case TEXT_KF_LW_SIGN: + entrance = ENTR_LOST_WOODS_SOUTH_EXIT; + break; + case TEXT_HF_LON_LON_SIGN: + entrance = ENTR_LON_LON_RANCH_ENTRANCE; + break; + case TEXT_LA_SIGN: + entrance = ENTR_LAKE_HYLIA_NORTH_EXIT; + break; + case TEXT_LA_LAB_SIGN: + entrance = ENTR_LAKESIDE_LABORATORY_0; + break; + case TEXT_GV_SIGN: + if (gPlayState->sceneNum == SCENE_HYRULE_FIELD) { + entrance = ENTR_GERUDO_VALLEY_EAST_EXIT; + } else { + entrance = ENTR_GERUDO_VALLEY_WEST_EXIT; + } + break; + case TEXT_ZD_SHOP_SIGN: + entrance = ENTR_ZORA_SHOP_0; + break; + case TEXT_OUTSIDE_KOKIRI_SIGN: + entrance = ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT; + break; + case TEXT_OUTSIDE_MARKET_SIGN: + entrance = ENTR_LON_LON_RANCH_ENTRANCE; + break; + case TEXT_MIDO_HOUSE_SIGN: + entrance = ENTR_MIDOS_HOUSE_0; + break; + case TEXT_KNOW_IT_ALL_HOUSE_SIGN: + entrance = ENTR_KNOW_IT_ALL_BROS_HOUSE_0; + break; + case TEXT_TWINS_HOUSE_SIGN: + entrance = ENTR_TWINS_HOUSE_0; + break; + case TEXT_SARIAS_HOUSE_SIGN: + entrance = ENTR_SARIAS_HOUSE_0; + break; + case TEXT_NO_DIVING_SIGN: + entrance = ENTR_LAKE_HYLIA_RIVER_EXIT; + break; + } + if (entrance != -1) { + auto entranceCtx = ctx->GetEntranceShuffler(); + for (size_t i = 0; i < ENTRANCE_OVERRIDES_MAX_COUNT; i++) { + if (Entrance_EntranceIsNull(&entranceCtx->entranceOverrides[i])) { + break; + } + if (entranceCtx->entranceOverrides[i].index == entrance) { + s16 overrideIndex = entranceCtx->entranceOverrides[i].override; + Entrance_SetEntranceDiscovered(entrance, false); + auto data = GetEntranceData(overrideIndex); + font->charTexBuf[0] = (TEXTBOX_TYPE_WOODEN << 4) | TEXTBOX_POS_BOTTOM; + return msgCtx->msgLength = font->msgLength = SohUtils::CopyStringToCharBuffer( + buffer, data->source + CustomMessage::MESSAGE_END(), maxBufferSize); + } + } + } + } + bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL); Player* player = GET_PLAYER(play); @@ -2332,7 +2477,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else { messageEntry = ctx->GetHint(stoneHint)->GetHintMessage(MF_AUTO_FORMAT); } - } else if ((textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT)) { + } else if (textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT) { // rando hints at altar messageEntry = (LINK_IS_ADULT) ? ctx->GetHint(RH_ALTAR_ADULT)->GetHintMessage(MF_AUTO_FORMAT) : ctx->GetHint(RH_ALTAR_CHILD)->GetHintMessage(MF_AUTO_FORMAT); diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index fc63f96c8..6c357c612 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2782,7 +2782,6 @@ void Message_OpenText(PlayState* play, u16 textId) { gSaveContext.eventInf[0] = gSaveContext.eventInf[1] = gSaveContext.eventInf[2] = gSaveContext.eventInf[3] = 0; } - // RANDOTODO: Use this for ice trap messages if (CustomMessage_RetrieveIfExists(play)) { osSyncPrintf("Found custom message"); if (gSaveContext.language == LANGUAGE_JPN) { From ba693ecac4c8895c5bcfa154d5190d67f51cabbe Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 16 Sep 2025 18:57:33 -0700 Subject: [PATCH 54/98] Search Exclusion and Search Widgets (#5656) * Implement widget search exclusion. Exclude all external windows from the search. * Add second column to search results for non-widget results. * Implement extra search index. Add various controls, audio editor, and tracker options to the extra search index. Fix capitalization on a few options. Add click-to-view functionality to extra search column. * Add extraSearchWidgets for searching through non-menu widgets. Convert Controls extraSearches to widgets. Used to display in-window, as well as provide reference to extraSearchWidgets. * Swap Audio search to menu widget search system. * Fix missing static on a ShipInit instance. * Implement SearchWidgets in popout windows. Remove remaining vestiges of custom search. * Add SearchWidget for randomizing audio on seed gen. * Remove comments on color picker entries in WidgetType. * Put all search results in middle column for width management. Change combobox alignment and label position in search results to unify them all to left and above for better organization. Add "Search Results" text to header of results page for clarification. * clang --- soh/soh/Enhancements/Presets/Presets.cpp | 4 +- soh/soh/Enhancements/audio/AudioEditor.cpp | 175 +++++---- .../controls/SohInputEditorWindow.cpp | 95 +++-- .../randomizer/randomizer_check_tracker.cpp | 176 +++++---- .../randomizer/randomizer_item_tracker.cpp | 353 +++++++++++------- .../ObjectExtension/ActorMaximumHealth.cpp | 2 +- soh/soh/SohGui/Menu.cpp | 115 +++++- soh/soh/SohGui/Menu.h | 1 + soh/soh/SohGui/MenuTypes.h | 129 ++++--- soh/soh/SohGui/SohMenu.cpp | 5 +- soh/soh/SohGui/SohMenuDevTools.cpp | 10 + soh/soh/SohGui/SohMenuEnhancements.cpp | 4 + soh/soh/SohGui/SohMenuRandomizer.cpp | 8 + soh/soh/SohGui/SohMenuSettings.cpp | 3 + soh/soh/SohGui/UIWidgets.hpp | 58 +++ 15 files changed, 774 insertions(+), 364 deletions(-) diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 0132efd6c..b8503cbc6 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -437,7 +437,9 @@ void PresetsCustomWidget(WidgetInfo& info) { void RegisterPresetsWidgets() { SohGui::mSohMenu->AddSidebarEntry("Settings", "Presets", 1); WidgetPath path = { "Settings", "Presets", SECTION_COLUMN_1 }; - SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM).CustomFunction(PresetsCustomWidget); + SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM) + .CustomFunction(PresetsCustomWidget) + .HideInSearch(true); presetFolder = Ship::Context::GetInstance()->GetPathRelativeToAppDirectory("presets"); std::fill_n(saveSection, PRESET_SECTION_MAX, true); LoadPresets(); diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index f031048f2..18b5cec1a 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -11,7 +11,7 @@ #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" #include -#include "soh/SohGui/UIWidgets.hpp" +#include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" #include "AudioCollection.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -25,6 +25,23 @@ Vec3f pos = { 0.0f, 0.0f, 0.0f }; f32 freqScale = 1.0f; s8 reverbAdd = 0; +using namespace UIWidgets; + +static WidgetInfo lowHpAlarm; +static WidgetInfo naviCall; +static WidgetInfo enemyProx; +static WidgetInfo leadingMusic; +static WidgetInfo displaySeqName; +static WidgetInfo ovlDuration; +static WidgetInfo voicePitch; +static WidgetInfo randoMusicOnSceneChange; +static WidgetInfo randomAudioOnSeedGen; +static WidgetInfo lowerOctaves; + +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + // Authentic sequence counts // used to ensure we have enough to shuffle #define SEQ_COUNT_BGM_WORLD 30 @@ -527,75 +544,22 @@ void AudioEditor::DrawElement() { ImGui::TableNextRow(); ImGui::TableNextColumn(); if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) { - UIWidgets::CVarCheckbox( - "Mute Low HP Alarm", CVAR_AUDIO("LowHpAlarm"), - UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Disable the low HP beeping sound.")); - UIWidgets::CVarCheckbox("Disable Navi Call Audio", CVAR_AUDIO("DisableNaviCallAudio"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Disables the voice audio when Navi calls you.")); - UIWidgets::CVarCheckbox( - "Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Disables the music change when getting close to enemies. Useful for hearing " - "your custom music for each scene more often.")); - UIWidgets::CVarCheckbox( - "Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing " - "your custom music in the Lost Woods if you don't need the navigation assitance " - "the volume changing provides. If toggling this while in the Lost Woods, reload " - "the area for the effect to kick in.")); - UIWidgets::CVarCheckbox( - "Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new " - "sequence " - "is loaded to the main sequence player (does not apply to fanfares or enemy BGM).")); - UIWidgets::CVarSliderInt("Overlay Duration: %d seconds", CVAR_AUDIO("SeqNameOverlayDuration"), - UIWidgets::IntSliderOptions() - .Min(1) - .Max(10) - .DefaultValue(5) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); - UIWidgets::CVarSliderFloat("Link's voice pitch multiplier", CVAR_AUDIO("LinkVoiceFreqMultiplier"), - UIWidgets::FloatSliderOptions() - .IsPercentage() - .Min(0.4f) - .Max(2.5f) - .DefaultValue(1.0f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + SohGui::mSohMenu->MenuDrawItem(lowHpAlarm, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(naviCall, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(enemyProx, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(leadingMusic, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(displaySeqName, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(ovlDuration, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(voicePitch, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPos().y + 40.f); if (UIWidgets::Button("Reset##linkVoiceFreqMultiplier", UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f); } - UIWidgets::CVarCheckbox( - "Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip( - "Enables randomizing all unlocked music and sound effects when you enter a new scene.")); - UIWidgets::CVarCheckbox("Randomize All Music and Sound Effects on Randomizer Generation", - CVAR_AUDIO("RandomizeAllOnRandoGen"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked music and sound effects when " - "you generate a new randomizer.")); - UIWidgets::CVarCheckbox( - "Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Some custom sequences may have notes that are too high for the game's audio " - "engine to play. Enabling this checkbox will cause these notes to drop a " - "couple of octaves so they can still harmonize with the other notes of the " - "sequence.")); + SohGui::mSohMenu->MenuDrawItem(randoMusicOnSceneChange, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(randomAudioOnSeedGen, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(lowerOctaves, ImGui::GetContentRegionAvail().x, THEME_COLOR); } ImGui::EndChild(); ImGui::EndTable(); @@ -849,3 +813,86 @@ void AudioEditor_UnlockAll() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } + +void RegisterAudioWidgets() { + lowHpAlarm = { .name = "Mute Low HP Alarm", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + lowHpAlarm.CVar(CVAR_AUDIO("LowHpAlarm")) + .Options(CheckboxOptions().Color(THEME_COLOR).Tooltip("Disable the low HP beeping sound.")); + SohGui::mSohMenu->AddSearchWidget({ lowHpAlarm, "Enhancements", "Audio Editor", "Audio Options" }); + + naviCall = { .name = "Disable Navi Call Audio", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + naviCall.CVar(CVAR_AUDIO("DisableNaviCallAudio")) + .Options(CheckboxOptions().Color(THEME_COLOR).Tooltip("Disables the voice audio when Navi calls you.")); + SohGui::mSohMenu->AddSearchWidget({ naviCall, "Enhancements", "Audio Editor", "Audio Options" }); + + enemyProx = { .name = "Disable Enemy Proximity Music", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + enemyProx.CVar(CVAR_AUDIO("EnemyBGMDisable")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Disables the music change when getting close to enemies. Useful for hearing " + "your custom music for each scene more often.")); + + leadingMusic = { .name = "Disable Leading Music in Lost Woods", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + leadingMusic.CVar(CVAR_AUDIO("LostWoodsConsistentVolume")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing " + "your custom music in the Lost Woods if you don't need the navigation assitance " + "the volume changing provides. If toggling this while in the Lost Woods, reload " + "the area for the effect to kick in.")); + SohGui::mSohMenu->AddSearchWidget({ leadingMusic, "Enhancements", "Audio Editor", "Audio Options" }); + + displaySeqName = { .name = "Display Sequence Name on Overlay", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + displaySeqName.CVar(CVAR_AUDIO("SeqNameOverlay")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new " + "sequence " + "is loaded to the main sequence player (does not apply to fanfares or enemy BGM).")); + SohGui::mSohMenu->AddSearchWidget({ displaySeqName, "Enhancements", "Audio Editor", "Audio Options" }); + + ovlDuration = { .name = "Overlay Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT }; + ovlDuration.CVar(CVAR_AUDIO("SeqNameOverlayDuration")) + .Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(10).DefaultValue(5).Size(ImVec2(300.0f, 0.0f))); + SohGui::mSohMenu->AddSearchWidget({ ovlDuration, "Enhancements", "Audio Editor", "Audio Options" }); + + voicePitch = { .name = "Link's Voice Pitch Multiplier", .type = WidgetType::WIDGET_CVAR_SLIDER_FLOAT }; + voicePitch.CVar(CVAR_AUDIO("LinkVoiceFreqMultiplier")) + .Options(FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.4f) + .Max(2.5f) + .DefaultValue(1.0f) + .Size(ImVec2(300.0f, 0.0f))); + SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" }); + + randoMusicOnSceneChange = { .name = "Randomize All Music and Sound Effects on New Scene", + .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + randoMusicOnSceneChange.CVar(CVAR_AUDIO("RandomizeAllOnNewScene")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene.")); + SohGui::mSohMenu->AddSearchWidget({ randoMusicOnSceneChange, "Enhancements", "Audio Editor", "Audio Options" }); + + randomAudioOnSeedGen = { .name = "Randomize All Music and Sound Effects on Randomizer Generation", + .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + randomAudioOnSeedGen.CVar(CVAR_AUDIO("RandomizeAllOnRandoGen")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables randomizing all unlocked music and sound effects when you generate a new " + "randomizer. Respects locks already in place.")); + SohGui::mSohMenu->AddSearchWidget({ randomAudioOnSeedGen, "Enhancements", "Audio Editor", "Audio Options" }); + + lowerOctaves = { .name = "Lower Octaves of Unplayable High Notes", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + lowerOctaves.CVar(CVAR_AUDIO("ExperimentalOctaveDrop")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Some custom sequences may have notes that are too high for the game's audio " + "engine to play. Enabling this checkbox will cause these notes to drop a " + "couple of octaves so they can still harmonize with the other notes of the " + "sequence.")); + SohGui::mSohMenu->AddSearchWidget({ lowerOctaves, "Enhancements", "Audio Editor", "Audio Options" }); +} + +static RegisterMenuInitFunc initAudioWidgets(RegisterAudioWidgets); diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index 41a31f8be..6fc7f6624 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -1,7 +1,7 @@ #include "SohInputEditorWindow.h" #include #include "soh/OTRGlobals.h" -#include "soh/SohGui/UIWidgets.hpp" +#include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" #include "z64.h" #include "soh/cvar_prefixes.h" @@ -13,6 +13,17 @@ using namespace UIWidgets; +static WidgetInfo freeLook; +static WidgetInfo mouseControl; +static WidgetInfo rightStickOcarina; +static WidgetInfo dpadOcarina; +static WidgetInfo dpadPause; +static WidgetInfo dpadText; + +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + SohInputEditorWindow::~SohInputEditorWindow() { } @@ -1321,8 +1332,8 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() { ImGui::SetCursorPos(ImVec2(cursor.x, cursor.y + 5)); CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR); - CVarCheckbox("Dpad Ocarina Playback", CVAR_SETTING("CustomOcarina.Dpad"), checkOpt); - CVarCheckbox("Right Stick Ocarina Playback", CVAR_SETTING("CustomOcarina.RightStick"), checkOpt); + SohGui::mSohMenu->MenuDrawItem(dpadOcarina, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(rightStickOcarina, ImGui::GetContentRegionAvail().x, THEME_COLOR); CVarCheckbox("Customize Ocarina Controls", CVAR_SETTING("CustomOcarina.Enabled"), checkOpt); if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) { @@ -1354,12 +1365,8 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() { void SohInputEditorWindow::DrawCameraControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); - CVarCheckbox( - "Enable Mouse Controls", CVAR_SETTING("EnableMouse"), - CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Allows for using the mouse to control the camera (must enable Free Look), " - "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)")); + SohGui::mSohMenu->MenuDrawItem(mouseControl, ImGui::GetContentRegionAvail().x, THEME_COLOR); + Ship::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail()); CVarCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim"), CheckboxOptions() @@ -1427,14 +1434,7 @@ void SohInputEditorWindow::DrawCameraControlPanel() { ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); Ship::GuiWindow::BeginGroupPanel("Third-Person Camera", ImGui::GetContentRegionAvail()); - CVarCheckbox( - "Free Look", CVAR_SETTING("FreeLook.Enabled"), - CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the " - "controller config menu, and map the camera stick to the right stick.\n" - "Doesn't work in areas were the game locks the camera.\n" - "Scene reload may be necessary to enable.")); + SohGui::mSohMenu->MenuDrawItem(freeLook, ImGui::GetContentRegionAvail().x, THEME_COLOR); CVarCheckbox("Invert Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis"), CheckboxOptions().Color(THEME_COLOR).Tooltip("Inverts the Camera X Axis in:\n-Free look")); CVarCheckbox( @@ -1467,16 +1467,8 @@ void SohInputEditorWindow::DrawDpadControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); Ship::GuiWindow::BeginGroupPanel("D-Pad Options", ImGui::GetContentRegionAvail()); - CVarCheckbox("D-pad Support on Pause Screen", CVAR_SETTING("DPadOnPause"), - CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold " - "C-Up to equip instead of navigate")); - CVarCheckbox("D-pad Support in Text Boxes", CVAR_SETTING("DpadInText"), - CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry " - "screens with the D-pad")); + SohGui::mSohMenu->MenuDrawItem(dpadPause, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(dpadText, ImGui::GetContentRegionAvail().x, THEME_COLOR); if (!CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CVarGetInteger(CVAR_SETTING("DpadInText"), 0)) { ImGui::BeginDisabled(); @@ -1902,3 +1894,52 @@ void SohInputEditorWindow::DrawElement() { ImGui::PopStyleColor(3); ImGui::PopFont(); } + +void RegisterInputEditorWidgets() { + dpadOcarina = { .name = "Dpad Ocarina Playback", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + dpadOcarina.CVar(CVAR_SETTING("CustomOcarina.Dpad")).Options(CheckboxOptions().Color(THEME_COLOR)); + SohGui::mSohMenu->AddSearchWidget({ dpadOcarina, "Settings", "Controls", "Ocarina Controls", "" }); + + freeLook = { .name = "Free Look", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + freeLook.CVar(CVAR_SETTING("FreeLook.Enabled")) + .Options( + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip( + "Enables free look camera control\nNote: You must remap C buttons off of the right stick in the " + "controller config menu, and map the camera stick to the right stick.\n" + "Doesn't work in areas were the game locks the camera.\n" + "Scene reload may be necessary to enable.")); + SohGui::mSohMenu->AddSearchWidget({ freeLook, "Settings", "Controls", "Camera Controls" }); + + mouseControl = { .name = "Enable Mouse Controls", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + mouseControl.CVar(CVAR_SETTING("EnableMouse")) + .Options( + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Allows for using the mouse to control the camera (must enable Free Look), " + "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)")); + SohGui::mSohMenu->AddSearchWidget({ mouseControl, "Settings", "Controls", "Camera Controls" }); + + rightStickOcarina = { .name = "Right Stick Ocarina Playback", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + rightStickOcarina.CVar(CVAR_SETTING("CustomOcarina.RightStick")).Options(CheckboxOptions().Color(THEME_COLOR)); + SohGui::mSohMenu->AddSearchWidget({ rightStickOcarina, "Settings", "Controls", "Ocarina Controls" }); + + dpadPause = { .name = "D-pad Support on Pause Screen", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + dpadPause.CVar(CVAR_SETTING("DPadOnPause")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold " + "C-Up to equip instead of navigate")); + SohGui::mSohMenu->AddSearchWidget({ dpadPause, "Settings", "Controls", "Dpad Controls" }); + + dpadText = { .name = "D-pad Support in Text Boxes", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + dpadText.CVar(CVAR_SETTING("DpadInText")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry " + "screens with the D-pad")); + SohGui::mSohMenu->AddSearchWidget({ dpadText, "Settings", "Controls", "Dpad Controls" }); +} + +static RegisterMenuInitFunc initInputWidgets(RegisterInputEditorWidgets); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 52611b89b..1859ed473 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -8,6 +8,7 @@ #include "soh/ResourceManagerHelpers.h" #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" +#include "soh/SohGui/SohMenu.h" #include "dungeon.h" #include "entrance.h" #include "location_access.h" @@ -39,9 +40,21 @@ extern std::vector dungeonRewardMedallions; extern std::vector songItems; extern std::vector equipmentItems; +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + using json = nlohmann::json; +using namespace UIWidgets; namespace CheckTracker { +static WidgetInfo backgroundColorWidget; +static WidgetInfo windowTypeWidget; +static WidgetInfo dungeonSpoilerWidget; +static WidgetInfo hideUnshuffledShopWidget; +static WidgetInfo showGSWidget; +static WidgetInfo showLogicWidget; +static WidgetInfo checkAvailabilityWidget; // settings bool showShops; @@ -936,43 +949,6 @@ void SetAreaSpoiled(RandomizerCheckArea rcArea) { } void CheckTrackerWindow::DrawElement() { - Color_Background = CVarGetColor(CVAR_TRACKER_CHECK("BgColor.Value"), Color_Bg_Default); - Color_Area_Incomplete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); - Color_Area_Incomplete_Extra = - CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); - Color_Area_Complete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); - Color_Area_Complete_Extra = - CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); - Color_Unchecked_Main = CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.MainColor.Value"), Color_Main_Default); - Color_Unchecked_Extra = - CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.ExtraColor.Value"), Color_Unchecked_Extra_Default); - Color_Skipped_Main = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.MainColor.Value"), Color_Main_Default); - Color_Skipped_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.ExtraColor.Value"), Color_Skipped_Extra_Default); - Color_Seen_Main = CVarGetColor(CVAR_TRACKER_CHECK("Seen.MainColor.Value"), Color_Main_Default); - Color_Seen_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Seen.ExtraColor.Value"), Color_Seen_Extra_Default); - Color_Hinted_Main = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.MainColor.Value"), Color_Main_Default); - Color_Hinted_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.ExtraColor.Value"), Color_Hinted_Extra_Default); - Color_Collected_Main = CVarGetColor(CVAR_TRACKER_CHECK("Collected.MainColor.Value"), Color_Main_Default); - Color_Collected_Extra = - CVarGetColor(CVAR_TRACKER_CHECK("Collected.ExtraColor.Value"), Color_Collected_Extra_Default); - Color_Scummed_Main = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.MainColor.Value"), Color_Main_Default); - Color_Scummed_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.ExtraColor.Value"), Color_Scummed_Extra_Default); - Color_Saved_Main = CVarGetColor(CVAR_TRACKER_CHECK("Saved.MainColor.Value"), Color_Main_Default); - Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor.Value"), Color_Saved_Extra_Default); - hideUnchecked = CVarGetInteger(CVAR_TRACKER_CHECK("Unchecked.Hide"), 0); - hideScummed = CVarGetInteger(CVAR_TRACKER_CHECK("Scummed.Hide"), 0); - hideSeen = CVarGetInteger(CVAR_TRACKER_CHECK("Seen.Hide"), 0); - hideSkipped = CVarGetInteger(CVAR_TRACKER_CHECK("Skipped.Hide"), 0); - hideSaved = CVarGetInteger(CVAR_TRACKER_CHECK("Saved.Hide"), 0); - hideCollected = CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0); - showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); - mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0); - showLogicTooltip = CVarGetInteger(CVAR_TRACKER_CHECK("ShowLogic"), 0); - enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); - onlyShowAvailable = CVarGetInteger(CVAR_TRACKER_CHECK("OnlyShowAvailable"), 0); - - hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); - alwaysShowGS = CVarGetInteger(CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), 0); if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { if (CVarGetInteger(CVAR_TRACKER_CHECK("ShowOnlyPaused"), 0) && (gPlayState == nullptr || gPlayState->pauseCtx.state == 0)) { @@ -2089,22 +2065,14 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::TableHeadersRow(); ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - UIWidgets::CVarColorPicker("BG Color", CVAR_TRACKER_CHECK("BgColor"), Color_Bg_Default, true, - UIWidgets::ColorPickerResetButton | UIWidgets::ColorPickerRandomButton, THEME_COLOR); - ImGui::PopItemWidth(); + SohGui::mSohMenu->MenuDrawItem(backgroundColorWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); - UIWidgets::CVarCombobox("Window Type", CVAR_TRACKER_CHECK("WindowType"), windowType, - UIWidgets::ComboboxOptions() - .LabelPosition(UIWidgets::LabelPositions::Far) - .ComponentAlignment(UIWidgets::ComponentAlignments::Right) - .Color(THEME_COLOR) - .DefaultIndex(TRACKER_WINDOW_WINDOW)); + SohGui::mSohMenu->MenuDrawItem(windowTypeWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { UIWidgets::CVarCheckbox("Enable Dragging", CVAR_TRACKER_CHECK("Draggable"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); - UIWidgets::CVarCheckbox("Only enable while paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), + UIWidgets::CVarCheckbox("Only Enable While Paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCombobox("Display Mode", CVAR_TRACKER_CHECK("DisplayType"), displayType, UIWidgets::ComboboxOptions() @@ -2129,41 +2097,17 @@ void CheckTrackerSettingsWindow::DrawElement() { } } ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - UIWidgets::CVarCheckbox("Vanilla/MQ Dungeon Spoilers", CVAR_TRACKER_CHECK("MQSpoilers"), - UIWidgets::CheckboxOptions() - .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. " - "Otherwise, Vanilla/MQ dungeon locations must be unlocked.") - .Color(THEME_COLOR)); + SohGui::mSohMenu->MenuDrawItem(dungeonSpoilerWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::EndDisabled(); - if (UIWidgets::CVarCheckbox( - "Hide unshuffled shop item checks", CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), - UIWidgets::CheckboxOptions() - .Tooltip("If enabled, will prevent the tracker from displaying slots with non-shop-item shuffles.") - .Color(THEME_COLOR))) { - hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); - UpdateFilters(); - } - if (UIWidgets::CVarCheckbox( - "Always show gold skulltulas", CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), - UIWidgets::CheckboxOptions() - .Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings.") - .Color(THEME_COLOR))) { - alwaysShowGS = !alwaysShowGS; - UpdateFilters(); - } - UIWidgets::CVarCheckbox("Show Logic", CVAR_TRACKER_CHECK("ShowLogic"), - UIWidgets::CheckboxOptions() - .Tooltip("If enabled, will show a check's logic when hovering over it.") - .Color(THEME_COLOR)); + + SohGui::mSohMenu->MenuDrawItem(hideUnshuffledShopWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + + SohGui::mSohMenu->MenuDrawItem(showGSWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + + SohGui::mSohMenu->MenuDrawItem(showLogicWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - if (UIWidgets::CVarCheckbox("Enable Available Checks", CVAR_TRACKER_CHECK("EnableAvailableChecks"), - UIWidgets::CheckboxOptions() - .Tooltip("If enabled, will show the checks that are available to be collected " - "with your current progress.") - .Color(THEME_COLOR))) { - enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); - RecalculateAvailableChecks(); - } + SohGui::mSohMenu->MenuDrawItem(checkAvailabilityWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::EndDisabled(); // Filtering settings @@ -2240,4 +2184,74 @@ void CheckTrackerWindow::InitElement() { void CheckTrackerWindow::UpdateElement() { } + +void RegisterCheckTrackerWidgets() { + backgroundColorWidget = { .name = "Background Color##CheckTrackerBgColor", + .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; + backgroundColorWidget.CVar(CVAR_TRACKER_ITEM("BgColor")) + .Options( + ColorPickerOptions().Color(THEME_COLOR).DefaultValue(Color_Bg_Default).UseAlpha().ShowReset().ShowRandom()); + SohGui::mSohMenu->AddSearchWidget({ backgroundColorWidget, "Randomizer", "Check Tracker", "General Settings" }); + + windowTypeWidget = { .name = "Window Type", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + windowTypeWidget.CVar(CVAR_TRACKER_ITEM("WindowType")) + .Options(ComboboxOptions() + .DefaultIndex(TRACKER_WINDOW_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(windowType)); + SohGui::mSohMenu->AddSearchWidget({ windowTypeWidget, "Randomizer", "Check Tracker", "General Settings" }); + + dungeonSpoilerWidget = { .name = "Vanilla/MQ Dungeon Spoilers", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + dungeonSpoilerWidget.CVar(CVAR_TRACKER_CHECK("MQSpoilers")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. " + "Otherwise, Vanilla/MQ dungeon locations must be unlocked.")); + SohGui::mSohMenu->AddSearchWidget({ dungeonSpoilerWidget, "Randomizer", "Check Tracker", "General Settings" }); + + hideUnshuffledShopWidget = { .name = "Hide Unshuffled Shop Item Checks", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + hideUnshuffledShopWidget.CVar(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks")) + .Options( + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("If enabled, will prevent the tracker from displaying slots with non-shop-item shuffles.")) + .Callback([&](WidgetInfo& info) { + hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); + UpdateFilters(); + }); + SohGui::mSohMenu->AddSearchWidget({ hideUnshuffledShopWidget, "Randomizer", "Check Tracker", "General Settings" }); + + showGSWidget = { .name = "Always Show Gold Skulltulas", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + showGSWidget.CVar(CVAR_TRACKER_CHECK("AlwaysShowGSLocs")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings.")) + .Callback([&](WidgetInfo& info) { + alwaysShowGS = !alwaysShowGS; + UpdateFilters(); + }); + SohGui::mSohMenu->AddSearchWidget({ showGSWidget, "Randomizer", "Check Tracker", "General Settings" }); + + showLogicWidget = { .name = "Show Logic", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + showLogicWidget.CVar(CVAR_TRACKER_CHECK("ShowLogic")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("If enabled, will show a check's logic when hovering over it.")); + SohGui::mSohMenu->AddSearchWidget({ showLogicWidget, "Randomizer", "Check Tracker", "General Settings" }); + + checkAvailabilityWidget = { .name = "Enable Available Checks", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + checkAvailabilityWidget.CVar(CVAR_TRACKER_CHECK("EnableAvailableChecks")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("If enabled, will show the checks that are available to be collected " + "with your current progress.")) + .Callback([&](WidgetInfo& info) { + enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); + RecalculateAvailableChecks(); + }); +} + +static RegisterMenuInitFunc initCheckTrackerWidgets(RegisterCheckTrackerWidgets); } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 81144c7a7..1e677df1a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -1,20 +1,22 @@ -#include "randomizer_item_tracker.h" -#include "soh/util.h" -#include "soh/OTRGlobals.h" -#include "soh/cvar_prefixes.h" -#include "soh/SaveManager.h" -#include "soh/ResourceManagerHelpers.h" -#include "soh/SohGui/UIWidgets.hpp" -#include "soh/SohGui/SohGui.hpp" -#include "randomizerTypes.h" - +#include #include #include #include + #include -#include "soh/Enhancements/game-interactor/GameInteractor.h" + #include "randomizer_check_tracker.h" -#include +#include "randomizer_item_tracker.h" +#include "randomizerTypes.h" +#include "soh/cvar_prefixes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/SaveManager.h" +#include "soh/SohGui/SohGui.hpp" +#include "soh/SohGui/SohMenu.h" +#include "soh/SohGui/UIWidgets.hpp" +#include "soh/util.h" extern "C" { #include @@ -42,6 +44,27 @@ bool shouldUpdateVectors = true; std::vector mainWindowItems = {}; +static WidgetInfo backgroundColor; +static WidgetInfo windowTypeWidget; +static WidgetInfo enableDraggingWidget; +static WidgetInfo onlyPausedWidget; +static WidgetInfo ammoTracking; +static WidgetInfo keyTracking; +static WidgetInfo triforcePieceCount; +static WidgetInfo dungeonItemTracking; +static WidgetInfo gregTracking; +static WidgetInfo triforcePieceTracking; +static WidgetInfo bossSoulsTracking; +static WidgetInfo ocarinaButtonTracking; +static WidgetInfo overworldKeysTracking; +static WidgetInfo fishingPoleTracking; +static WidgetInfo personalNotesWiget; +static WidgetInfo hookshotIdentWidget; + +namespace SohGui { +extern std::shared_ptr mSohMenu; +} + std::vector inventoryItems = { ITEM_TRACKER_ITEM(ITEM_STICK, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_NUT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BOMB, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BOW, 0, DrawItem), @@ -1764,24 +1787,15 @@ void ItemTrackerSettingsWindow::DrawElement() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true, - ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR); - + SohGui::mSohMenu->MenuDrawItem(backgroundColor, 250, THEME_COLOR); ImGui::PopItemWidth(); - if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, - ComboboxOptions() - .DefaultIndex(TRACKER_WINDOW_FLOATING) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } + SohGui::mSohMenu->MenuDrawItem(windowTypeWidget, 250, THEME_COLOR); if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) { if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), + if (CVarCheckbox("Only Enable While Paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } @@ -1822,14 +1836,7 @@ void ItemTrackerSettingsWindow::DrawElement() { IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR)); ImGui::NewLine(); - CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, - ComboboxOptions() - .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what the numbers under each item are tracking." - "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); + SohGui::mSohMenu->MenuDrawItem(ammoTracking, 250, THEME_COLOR); if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == @@ -1840,22 +1847,8 @@ void ItemTrackerSettingsWindow::DrawElement() { } } - CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, - ComboboxOptions() - .DefaultIndex(KEYS_COLLECTED_MAX) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for key tracking.")); - - CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), - itemTrackerTriforcePieceTrackOptions, - ComboboxOptions() - .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) - .ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above) - .Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for triforce piece tracking.")); + SohGui::mSohMenu->MenuDrawItem(keyTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(triforcePieceCount, 250, THEME_COLOR); ImGui::TableNextColumn(); @@ -1906,14 +1899,7 @@ void ItemTrackerSettingsWindow::DrawElement() { .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } + SohGui::mSohMenu->MenuDrawItem(dungeonItemTracking, 250, THEME_COLOR); if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != SECTION_DISPLAY_HIDDEN) { if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == @@ -1928,61 +1914,14 @@ void ItemTrackerSettingsWindow::DrawElement() { shouldUpdateVectors = true; } } - if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } + SohGui::mSohMenu->MenuDrawItem(gregTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(triforcePieceTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(bossSoulsTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(ocarinaButtonTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(overworldKeysTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(fishingPoleTracking, 250, THEME_COLOR); - if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - - if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, + if (CVarCombobox("Total Checks", CVAR_TRACKER_ITEM("TotalChecks.DisplayType"), minimalDisplayTypes, ComboboxOptions() .DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN) .ComponentAlignment(ComponentAlignments::Right) @@ -1991,23 +1930,8 @@ void ItemTrackerSettingsWindow::DrawElement() { shouldUpdateVectors = true; } - if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || - (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING && - CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) != - TRACKER_DISPLAY_COMBO_BUTTON)) { - if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, - ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN) - .ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far) - .Color(THEME_COLOR))) { - shouldUpdateVectors = true; - } - } - CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"), - CheckboxOptions() - .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.") - .Color(THEME_COLOR)); + SohGui::mSohMenu->MenuDrawItem(personalNotesWiget, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(hookshotIdentWidget, 250, THEME_COLOR); ImGui::PopStyleVar(1); ImGui::EndTable(); @@ -2026,3 +1950,178 @@ void ItemTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook(ItemTrackerOnFrame); } + +void RegisterItemTrackerWidgets() { + backgroundColor = { .name = "Background Color##gItemTrackerBgColor", .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; + backgroundColor.CVar(CVAR_TRACKER_ITEM("BgColor")) + .Options( + ColorPickerOptions().Color(THEME_COLOR).DefaultValue({ 0, 0, 0, 0 }).UseAlpha().ShowReset().ShowRandom()); + SohGui::mSohMenu->AddSearchWidget({ backgroundColor, "Randomizer", "Item Tracker", "General Settings" }); + + windowTypeWidget = { .name = "Window Type", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + windowTypeWidget.CVar(CVAR_TRACKER_ITEM("WindowType")) + .Options(ComboboxOptions() + .DefaultIndex(TRACKER_WINDOW_FLOATING) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(windowTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + SohGui::mSohMenu->AddSearchWidget({ windowTypeWidget, "Randomizer", "Item Tracker", "General Settings" }); + enableDraggingWidget; + onlyPausedWidget; + + ammoTracking = { .name = "Ammo/Capacity Tracking", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + ammoTracking.CVar(CVAR_TRACKER_ITEM("ItemCountType")) + .Options(ComboboxOptions() + .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(itemTrackerCapacityTrackOptions) + .Tooltip("Customize what the numbers under each item are tracking." + "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); + SohGui::mSohMenu->AddSearchWidget({ ammoTracking, "Randomizer", "Item Tracker", "General Settings" }); + + keyTracking = { .name = "Key Count Tracking", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + keyTracking.CVar(CVAR_TRACKER_ITEM("KeyCounts")) + .Options(ComboboxOptions() + .DefaultIndex(KEYS_COLLECTED_MAX) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(itemTrackerKeyTrackOptions) + .Tooltip("Customize what numbers are shown for key tracking.")); + SohGui::mSohMenu->AddSearchWidget({ keyTracking, "Randomizer", "Item Tracker", "General Settings" }); + + triforcePieceTracking = { .name = "Triforce Pieces", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + triforcePieceTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.TriforcePieces")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + SohGui::mSohMenu->AddSearchWidget({ triforcePieceTracking, "Randomizer", "Item Tracker", "General Settings" }); + + dungeonItemTracking = { .name = "Dungeon Items", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + dungeonItemTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.DungeonItems")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget( + { dungeonItemTracking, "Randomizer", "Item Tracker", "General Settings", "keys maps compasses icon" }); + + gregTracking = { .name = "Greg", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + gregTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.Greg")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(extendedDisplayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget({ gregTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + + bossSoulsTracking = { .name = "Boss Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + bossSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.Greg")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget({ bossSoulsTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + + triforcePieceCount = { .name = "Triforce Piece Count Tracking", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + triforcePieceCount.CVar(CVAR_TRACKER_ITEM("TriforcePieceCounts")) + .Options(ComboboxOptions() + .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(itemTrackerTriforcePieceTrackOptions) + .Tooltip("Customize what numbers are shown for triforce piece tracking.")); + SohGui::mSohMenu->AddSearchWidget({ triforcePieceCount, "Randomizer", "Item Tracker", "General Settings" }); + + ocarinaButtonTracking = { .name = "Ocarina Buttons", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + ocarinaButtonTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget( + { ocarinaButtonTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + + overworldKeysTracking = { .name = "Overworld Keys", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + overworldKeysTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.OverworldKeys")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget( + { overworldKeysTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + + fishingPoleTracking = { .name = "Fishing Pole", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + fishingPoleTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.FishingPole")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(extendedDisplayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget( + { fishingPoleTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + + personalNotesWiget = { .name = "Personal notes", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + static const char* notesDisabledTooltip = + "Disabled because tracker is set to floating and display combo is enabled."; + personalNotesWiget.CVar(CVAR_TRACKER_ITEM("DisplayType.Notes")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .PreFunc([&](WidgetInfo& info) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || + (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING && + CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) != + TRACKER_DISPLAY_COMBO_BUTTON)) { + info.options.get()->disabled = true; + info.options.get()->disabledTooltip = notesDisabledTooltip; + } + }) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget({ personalNotesWiget, "Randomizer", "Item Tracker", "General Settings" }); + + hookshotIdentWidget = { .name = "Show Hookshot Identifiers", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + hookshotIdentWidget.CVar(CVAR_SETTING("FreeLook.Enabled")) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.")); + SohGui::mSohMenu->AddSearchWidget( + { hookshotIdentWidget, "Settings", "Controls", "Camera Controls", "longshot icon" }); +} + +static RegisterMenuInitFunc initItemTrackerWidgets(RegisterItemTrackerWidgets); diff --git a/soh/soh/ObjectExtension/ActorMaximumHealth.cpp b/soh/soh/ObjectExtension/ActorMaximumHealth.cpp index 9c710822f..d8c74404b 100644 --- a/soh/soh/ObjectExtension/ActorMaximumHealth.cpp +++ b/soh/soh/ObjectExtension/ActorMaximumHealth.cpp @@ -26,4 +26,4 @@ static void ActorMaximumHealth_Register() { }); } -RegisterShipInitFunc actorMaximumHealthInit(ActorMaximumHealth_Register); \ No newline at end of file +static RegisterShipInitFunc actorMaximumHealthInit(ActorMaximumHealth_Register); diff --git a/soh/soh/SohGui/Menu.cpp b/soh/soh/SohGui/Menu.cpp index 98db5d239..aa83c314b 100644 --- a/soh/soh/SohGui/Menu.cpp +++ b/soh/soh/SohGui/Menu.cpp @@ -23,12 +23,19 @@ extern void Warp(); namespace SohGui { extern std::shared_ptr mModalWindow; } +std::vector extraSearchWidgets = {}; namespace Ship { std::string disabledTempTooltip; const char* disabledTooltip; bool disabledValue = false; +bool navigateToWidget = false; +const char* navigateMainEntry = ""; +const char* navigateSidebar = ""; +std::string navigateWidgetName = ""; +bool highlightWidget = false; + bool operator==(Color_RGB8 const& l, Color_RGB8 const& r) noexcept { return l.r == r.r && l.g == r.g && l.b == r.b; } @@ -128,6 +135,7 @@ void Menu::InitElement() { poppedSize.y = CVarGetInteger(CVAR_SETTING("Menu.PoppedHeight"), 800); poppedPos.x = CVarGetInteger(CVAR_SETTING("Menu.PoppedPos.x"), 0); poppedPos.y = CVarGetInteger(CVAR_SETTING("Menu.PoppedPos.y"), 0); + menuThemeIndex = static_cast(CVarGetInteger(CVAR_SETTING("Menu.Theme"), defaultThemeIndex)); UpdateWindowBackendObjects(); } @@ -186,7 +194,12 @@ bool ModernMenuHeaderEntry(std::string label) { uint32_t Menu::DrawSearchResults(std::string& menuSearchText) { int searchCount = 0; - if (ImGui::BeginChild("Search Results")) { + std::transform(menuSearchText.begin(), menuSearchText.end(), menuSearchText.begin(), ::tolower); + menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '), menuSearchText.end()); + ImGui::SetNextWindowSizeConstraints({ ImGui::GetContentRegionAvail().x / 2, 0 }, + { ImGui::GetContentRegionAvail().x / 2, ImGui::GetContentRegionAvail().y }); + if (ImGui::BeginChild("Search Results Col 1", { ImGui::GetContentRegionAvail().x / 2, 0 }, + ImGuiChildFlags_AutoResizeY, ImGuiWindowFlags_NoTitleBar)) { for (auto& menuLabel : menuOrder) { auto& menuEntry = menuEntries.at(menuLabel); for (auto& sidebarLabel : menuEntry.sidebarOrder) { @@ -195,29 +208,63 @@ uint32_t Menu::DrawSearchResults(std::string& menuSearchText) { auto& column = sidebar.columnWidgets.at(i); for (auto& info : column) { if (info.type == WIDGET_SEARCH || info.type == WIDGET_SEPARATOR || - info.type == WIDGET_SEPARATOR_TEXT || info.isHidden) { + info.type == WIDGET_SEPARATOR_TEXT || info.isHidden || info.hideInSearch) { continue; } const char* tooltip = info.options->tooltip; std::string widgetStr = std::string(info.name) + std::string(tooltip != NULL ? tooltip : ""); - std::transform(menuSearchText.begin(), menuSearchText.end(), menuSearchText.begin(), ::tolower); - menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '), - menuSearchText.end()); std::transform(widgetStr.begin(), widgetStr.end(), widgetStr.begin(), ::tolower); widgetStr.erase(std::remove(widgetStr.begin(), widgetStr.end(), ' '), widgetStr.end()); if (widgetStr.find(menuSearchText) != std::string::npos) { - MenuDrawItem(info, 90 / sidebar.columnCount, menuThemeIndex); + UIWidgets::ComponentAlignments backupAlignment; + UIWidgets::LabelPositions backupLabelPos; + if (info.type == WIDGET_COMBOBOX || info.type == WIDGET_CVAR_COMBOBOX) { + backupAlignment = + std::static_pointer_cast(info.options)->alignment; + backupLabelPos = + std::static_pointer_cast(info.options)->labelPosition; + std::static_pointer_cast(info.options)->alignment = + UIWidgets::ComponentAlignments::Left; + std::static_pointer_cast(info.options)->labelPosition = + UIWidgets::LabelPositions::Above; + } + MenuDrawItem(info, 400, menuThemeIndex); ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Gray)); std::string origin = fmt::format(" ({} -> {}, Col {})", menuEntry.label, sidebarLabel, i + 1); ImGui::Text("%s", origin.c_str()); ImGui::PopStyleColor(); searchCount++; + if (info.type == WIDGET_COMBOBOX || info.type == WIDGET_CVAR_COMBOBOX) { + std::static_pointer_cast(info.options)->alignment = + backupAlignment; + std::static_pointer_cast(info.options)->labelPosition = + backupLabelPos; + } } } } } } + for (auto& entry : extraSearchWidgets) { + if (entry.info.type == WIDGET_SEARCH || entry.info.type == WIDGET_SEPARATOR || + entry.info.type == WIDGET_SEPARATOR_TEXT || entry.info.isHidden || entry.info.hideInSearch) { + continue; + } + std::string widgetStr = + entry.info.name + entry.info.options->tooltip + entry.extraTerms + entry.sidebarName; + std::transform(widgetStr.begin(), widgetStr.end(), widgetStr.begin(), ::tolower); + widgetStr.erase(std::remove(widgetStr.begin(), widgetStr.end(), ' '), widgetStr.end()); + if (widgetStr.find(menuSearchText) != std::string::npos) { + MenuDrawItem(entry.info, 400, menuThemeIndex); + ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Gray)); + std::string origin = fmt::format(" ({} -> {}, {})", entry.menuName, entry.sidebarName, entry.location); + ImGui::Text("%s", origin.c_str()); + ImGui::PopStyleColor(); + searchCount++; + } + } + ImGui::EndChild(); } return searchCount; } @@ -227,6 +274,10 @@ void Menu::AddMenuEntry(std::string entryName, const char* entryCvar) { menuOrder.push_back(entryName); } +void Menu::AddSearchWidget(SearchWidget widget) { + extraSearchWidgets.push_back(widget); +} + std::unordered_map& Menu::GetDisabledMap() { return disabledMap; } @@ -449,6 +500,20 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me window->DrawElement(); } } break; + case WIDGET_CVAR_COLOR_PICKER: { + auto options = std::static_pointer_cast(widget.options); + uint32_t modifiers = 0; + if (options->showLock) + modifiers |= UIWidgets::ColorPickerLockCheck; + if (options->showRandom) + modifiers |= UIWidgets::ColorPickerRandomButton; + if (options->showReset) + modifiers |= UIWidgets::ColorPickerResetButton; + if (options->showRainbow) + modifiers |= UIWidgets::ColorPickerRainbowCheck; + UIWidgets::CVarColorPicker(widget.name.c_str(), widget.cVar, options->defaultValue, options->useAlpha, + modifiers, options->color); + } break; case WIDGET_SEARCH: { UIWidgets::PushStyleButton(menuThemeIndex); if (ImGui::Button("Clear")) { @@ -473,7 +538,6 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me return; } DrawSearchResults(menuSearchText); - ImGui::EndChild(); } break; default: break; @@ -501,6 +565,19 @@ void Menu::DrawElement() { for (auto& [reason, info] : disabledMap) { info.active = info.evaluation(info); } + const char* headerCvar = CVAR_SETTING("Menu.ActiveHeader"); + + if (navigateToWidget) { + if (menuEntries.contains(navigateMainEntry) && + menuEntries.at(navigateMainEntry).sidebars.contains(navigateSidebar)) { + menuSearch.Clear(); + CVarSetString(headerCvar, navigateMainEntry); + const char* sidebarCvar = menuEntries.at(navigateMainEntry).sidebarCvar; + CVarSetString(sidebarCvar, navigateSidebar); + highlightWidget = true; + } + navigateToWidget = false; + } raceDisableActive = CVarGetInteger(CVAR_SETTING("DisableChanges"), 0); @@ -569,7 +646,6 @@ void Menu::DrawElement() { ImGui::PushFont(OTRGlobals::Instance->fontStandardLargest); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f)); - const char* headerCvar = CVAR_SETTING("Menu.ActiveHeader"); std::string headerIndex = CVarGetString(headerCvar, "Settings"); ImVec2 pos = window->DC.CursorPos; float centerX = pos.x + windowWidth / 2 - (style.ItemSpacing.x * (menuEntries.size() + 1)); @@ -800,21 +876,26 @@ void Menu::DrawElement() { ImGuiWindowFlags_NoTitleBar); } if (headerSearch && menuSearchText.length() > 0) { + ImGui::AlignTextToFramePadding(); + ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest); + ImGui::Text("Search Results"); + ImGui::PopFont(); + ImGui::SameLine(); + UIWidgets::ButtonOptions clearBtnOpts = {}; + clearBtnOpts.size = UIWidgets::Sizes::Inline; + if (UIWidgets::Button("Clear Search", clearBtnOpts)) { + menuSearch.Clear(); + } + ImGui::BeginChild("searchSeparator", ImVec2(ImGui::GetContentRegionAvail().x / 2, 20), + ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY); + UIWidgets::Separator(true, true, 0, 10); + ImGui::EndChild(); uint32_t searchCount = DrawSearchResults(menuSearchText); if (searchCount == 0) { ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize("No results found").x) / 2); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.0f); ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "No results found"); } - ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize("Clear Search").x) / 2 - 10.0f); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.0f); - UIWidgets::ButtonOptions clearBtnOpts = {}; - clearBtnOpts.size = UIWidgets::Sizes::Inline; - if (UIWidgets::Button("Clear Search", clearBtnOpts)) { - menuSearch.Clear(); - } - - ImGui::EndChild(); } else { std::string menuLabel = menuEntries.at(headerIndex).label; if (MenuInit::GetUpdateFuncs().contains(menuLabel)) { diff --git a/soh/soh/SohGui/Menu.h b/soh/soh/SohGui/Menu.h index a7facffd1..1af541b8d 100644 --- a/soh/soh/SohGui/Menu.h +++ b/soh/soh/SohGui/Menu.h @@ -26,6 +26,7 @@ class Menu : public GuiWindow { void MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors menuThemeIndex); void AddMenuEntry(std::string entryName, const char* entryCvar); + void AddSearchWidget(SearchWidget widget); std::unordered_map& GetDisabledMap(); protected: diff --git a/soh/soh/SohGui/MenuTypes.h b/soh/soh/SohGui/MenuTypes.h index e96d015ef..911b688d7 100644 --- a/soh/soh/SohGui/MenuTypes.h +++ b/soh/soh/SohGui/MenuTypes.h @@ -24,10 +24,10 @@ typedef enum { struct WidgetInfo; struct disabledInfo; -using VoidFunc = void (*)(); -using DisableInfoFunc = bool (*)(disabledInfo&); +using VoidFunc = std::function; +using DisableInfoFunc = std::function; using DisableVec = std::vector; -using WidgetFunc = void (*)(WidgetInfo&); +using WidgetFunc = std::function; typedef enum { WIDGET_CHECKBOX, @@ -41,8 +41,8 @@ typedef enum { WIDGET_BUTTON, WIDGET_INPUT, WIDGET_CVAR_INPUT, - WIDGET_COLOR_24, // color picker without alpha - WIDGET_COLOR_32, // color picker with alpha + WIDGET_CVAR_COLOR_PICKER, + WIDGET_COLOR_PICKER, WIDGET_SEARCH, WIDGET_SEPARATOR, WIDGET_SEPARATOR_TEXT, @@ -72,9 +72,10 @@ typedef enum { // holds the widget values for a widget, contains all CVar types available from LUS. int32_t is used for boolean // evaluation using CVarVariant = std::variant; -using OptionsVariant = std::variant; +using OptionsVariant = + std::variant; // All the info needed for display and search of all widgets in the menu. // `name` is the label displayed, @@ -111,11 +112,13 @@ struct WidgetInfo { bool isHidden = false; bool sameLine = false; bool raceDisable = true; + bool hideInSearch = false; WidgetInfo& CVar(const char* cVar_) { cVar = cVar_; return *this; } + WidgetInfo& Options(OptionsVariant options_) { switch (type) { case WIDGET_AUDIO_BACKEND: @@ -138,6 +141,11 @@ struct WidgetInfo { options = std::make_shared(std::get(options_)); break; + case WIDGET_COLOR_PICKER: + case WIDGET_CVAR_COLOR_PICKER: + options = + std::make_shared(std::get(options_)); + break; case WIDGET_BUTTON: options = std::make_shared(std::get(options_)); break; @@ -155,48 +163,63 @@ struct WidgetInfo { } return *this; } + + WidgetInfo& Options(std::shared_ptr options_) { + options = options_; + return *this; + } + + WidgetInfo& Callback(WidgetFunc callback_) { + callback = callback_; + return *this; + } + + WidgetInfo& PreFunc(WidgetFunc preFunc_) { + preFunc = preFunc_; + return *this; + } + + WidgetInfo& PostFunc(WidgetFunc postFunc_) { + postFunc = postFunc_; + return *this; + } + + WidgetInfo& WindowName(const char* windowName_) { + windowName = windowName_; + return *this; + } + + WidgetInfo& ValuePointer(std::variant valuePointer_) { + valuePointer = valuePointer_; + return *this; + } + + WidgetInfo& SameLine(bool sameLine_) { + sameLine = sameLine_; + return *this; + } + + WidgetInfo& CustomFunction(WidgetFunc customFunction_) { + customFunction = customFunction_; + return *this; + } + + WidgetInfo& RaceDisable(bool disable) { + raceDisable = disable; + return *this; + } + + WidgetInfo& HideInSearch(bool hide) { + hideInSearch = hide; + return *this; + } + void ResetDisables() { isHidden = false; options->disabled = false; options->disabledTooltip = ""; activeDisables.clear(); } - WidgetInfo& Options(std::shared_ptr options_) { - options = options_; - return *this; - } - WidgetInfo& Callback(WidgetFunc callback_) { - callback = callback_; - return *this; - } - WidgetInfo& PreFunc(WidgetFunc preFunc_) { - preFunc = preFunc_; - return *this; - } - WidgetInfo& PostFunc(WidgetFunc postFunc_) { - postFunc = postFunc_; - return *this; - } - WidgetInfo& WindowName(const char* windowName_) { - windowName = windowName_; - return *this; - } - WidgetInfo& ValuePointer(std::variant valuePointer_) { - valuePointer = valuePointer_; - return *this; - } - WidgetInfo& SameLine(bool sameLine_) { - sameLine = sameLine_; - return *this; - } - WidgetInfo& CustomFunction(WidgetFunc customFunction_) { - customFunction = customFunction_; - return *this; - } - WidgetInfo& RaceDisable(bool disable) { - raceDisable = disable; - return *this; - } }; struct WidgetPath { @@ -269,6 +292,24 @@ struct MenuInit { } }; +struct SearchEntry { + // First four required + std::string widgetName; + std::string menuName; + std::string sidebarName; + std::string location; + std::string extraTerms = ""; +}; + +struct SearchWidget { + // First four required + WidgetInfo& info; + std::string menuName; + std::string sidebarName; + std::string location; + std::string extraTerms = ""; +}; + struct RegisterMenuInitFunc { RegisterMenuInitFunc(std::function initFunc) { auto& menuInitFuncs = MenuInit::GetInitFuncs(); diff --git a/soh/soh/SohGui/SohMenu.cpp b/soh/soh/SohGui/SohMenu.cpp index a71fd1cad..d5c2c0c1f 100644 --- a/soh/soh/SohGui/SohMenu.cpp +++ b/soh/soh/SohGui/SohMenu.cpp @@ -61,8 +61,9 @@ WidgetInfo& SohMenu::AddWidget(WidgetPath& pathInfo, std::string widgetName, Wid case WIDGET_WINDOW_BUTTON: widget.options = std::make_shared(); break; - case WIDGET_COLOR_24: - case WIDGET_COLOR_32: + case WIDGET_CVAR_COLOR_PICKER: + case WIDGET_COLOR_PICKER: + widget.options = std::make_shared(); break; case WIDGET_SEPARATOR_TEXT: case WIDGET_TEXT: diff --git a/soh/soh/SohGui/SohMenuDevTools.cpp b/soh/soh/SohGui/SohMenuDevTools.cpp index 2a0fcd62a..f9e113b55 100644 --- a/soh/soh/SohGui/SohMenuDevTools.cpp +++ b/soh/soh/SohGui/SohMenuDevTools.cpp @@ -124,6 +124,7 @@ void SohMenu::AddMenuDevTools() { .CVar(CVAR_WINDOW("SohStats")) .RaceDisable(false) .WindowName("Stats##Soh") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Stats Window.")); // Console @@ -132,6 +133,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Console", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("SohConsole")) .WindowName("Console##SoH") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Console Window.")); // Save Editor @@ -140,6 +142,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Save Editor", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("SaveEditor")) .WindowName("Save Editor") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Save Editor Window.")); // Hook Debugger @@ -148,6 +151,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Hook Debugger", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("HookDebugger")) .WindowName("Hook Debugger") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Hook Debugger Window.")); // Collision Viewer @@ -156,6 +160,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Collision Viewer", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("CollisionViewer")) .WindowName("Collision Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Collision Viewer Window.")); // Actor Viewer @@ -164,6 +169,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Actor Viewer", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("ActorViewer")) .WindowName("Actor Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Actor Viewer Window.")); // Display List Viewer @@ -172,6 +178,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Display List Viewer", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("DisplayListViewer")) .WindowName("Display List Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Display List Viewer Window.")); // Value Viewer @@ -180,6 +187,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Value Viewer", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("ValueViewer")) .WindowName("Value Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Value Viewer Window.")); // Message Viewer @@ -188,6 +196,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Message Viewer", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("MessageViewer")) .WindowName("Message Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Message Viewer Window.")); // Gfx Debugger @@ -196,6 +205,7 @@ void SohMenu::AddMenuDevTools() { AddWidget(path, "Popout Gfx Debugger", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("SohGfxDebugger")) .WindowName("GfxDebugger##SoH") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Gfx Debugger Window.")); } diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index b72f6298e..dd965be0a 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1844,6 +1844,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_WINDOW("CosmeticsEditor")) .RaceDisable(false) .WindowName("Cosmetics Editor") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Cosmetics Editor Window.")); // Audio Editor @@ -1853,6 +1854,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_WINDOW("AudioEditor")) .RaceDisable(false) .WindowName("Audio Editor") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Audio Editor Window.")); // Gameplay Stats @@ -1862,6 +1864,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_WINDOW("GameplayStats")) .RaceDisable(false) .WindowName("Gameplay Stats") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Gameplay Stats Window.")); // Time Splits @@ -1871,6 +1874,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_WINDOW("TimeSplits")) .RaceDisable(false) .WindowName("Time Splits") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Time Splits Window.")); // Timers diff --git a/soh/soh/SohGui/SohMenuRandomizer.cpp b/soh/soh/SohGui/SohMenuRandomizer.cpp index 47e651408..ad688740a 100644 --- a/soh/soh/SohGui/SohMenuRandomizer.cpp +++ b/soh/soh/SohGui/SohMenuRandomizer.cpp @@ -22,6 +22,7 @@ void SohMenu::AddMenuRandomizer() { AddWidget(path, "Popout Randomizer Settings Window", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("RandomizerSettings")) .WindowName("Randomizer Settings") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window.")); // Enhancements @@ -104,6 +105,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("PlandomizerEditor")) .RaceDisable(false) .WindowName("Plandomizer Editor") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window.")); // Item Tracker @@ -115,6 +117,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("ItemTracker")) .RaceDisable(false) .WindowName("Item Tracker") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Toggles the Item Tracker.").EmbedWindow(false)); AddWidget(path, "Item Tracker Settings", WIDGET_SEPARATOR_TEXT); @@ -122,6 +125,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("ItemTrackerSettings")) .RaceDisable(false) .WindowName("Item Tracker Settings") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Item Tracker Settings Window.")); // Entrance Tracker @@ -133,6 +137,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("EntranceTracker")) .RaceDisable(false) .WindowName("Entrance Tracker") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Toggles the Entrance Tracker.").EmbedWindow(false)); AddWidget(path, "Entrance Tracker Settings", WIDGET_SEPARATOR_TEXT); @@ -140,6 +145,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("EntranceTrackerSettings")) .RaceDisable(false) .WindowName("Entrance Tracker Settings") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Entrance Tracker Settings Window.")); // Check Tracker @@ -151,6 +157,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("CheckTracker")) .RaceDisable(false) .WindowName("Check Tracker") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Toggles the Check Tracker.").EmbedWindow(false)); AddWidget(path, "Check Tracker Settings", WIDGET_SEPARATOR_TEXT); @@ -158,6 +165,7 @@ void SohMenu::AddMenuRandomizer() { .CVar(CVAR_WINDOW("CheckTrackerSettings")) .RaceDisable(false) .WindowName("Check Tracker Settings") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Check Tracker Settings Window.")); } diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index 2472e325b..768370b85 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -433,6 +433,7 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_WINDOW("ControllerConfiguration")) .RaceDisable(false) .WindowName("Configure Controller") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Bindings Window.")); // Input Viewer @@ -443,6 +444,7 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_WINDOW("InputViewer")) .RaceDisable(false) .WindowName("Input Viewer") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Toggles the Input Viewer.").EmbedWindow(false)); AddWidget(path, "Input Viewer Settings", WIDGET_SEPARATOR_TEXT); @@ -450,6 +452,7 @@ void SohMenu::AddMenuSettings() { .CVar(CVAR_WINDOW("InputViewerSettings")) .RaceDisable(false) .WindowName("Input Viewer Settings") + .HideInSearch(true) .Options(WindowButtonOptions().Tooltip("Enables the separate Input Viewer Settings Window.")); // Notifications diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 0ed88bade..95590b1ce 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -162,6 +162,64 @@ struct ButtonOptions : WidgetOptions { } }; +struct ColorPickerOptions : WidgetOptions { + ImVec2 size = Sizes::Fill; + ImVec2 padding = ImVec2(10.0f, 8.0f); + Colors color = Colors::Gray; + Color_RGBA8 defaultValue = { 255, 255, 255, 255 }; + bool useAlpha, showReset, showRandom, showRainbow, showLock; + + ColorPickerOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + + ColorPickerOptions& Padding(ImVec2 padding_) { + padding = padding_; + return *this; + } + + ColorPickerOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + + ColorPickerOptions& ShowReset(bool showReset_ = true) { + showReset = showReset_; + return *this; + } + + ColorPickerOptions& ShowRandom(bool showRandom_ = true) { + showRandom = showRandom_; + return *this; + } + + ColorPickerOptions& ShowRainbow(bool showRainbow_ = true) { + showRainbow = showRainbow_; + return *this; + } + + ColorPickerOptions& ShowLock(bool showLock_ = true) { + showLock = showLock_; + return *this; + } + + ColorPickerOptions& UseAlpha(bool useAlpha_ = true) { + useAlpha = useAlpha_; + return *this; + } + + ColorPickerOptions& Color(Colors color_) { + color = color_; + return *this; + } + + ColorPickerOptions& DefaultValue(Color_RGBA8 defaultValue_) { + defaultValue = defaultValue_; + return *this; + } +}; + struct WindowButtonOptions : WidgetOptions { ImVec2 size = Sizes::Inline; ImVec2 padding = ImVec2(10.0f, 8.0f); From a88cac300e4b3769baed5a651e679e395a33b16b Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 17 Sep 2025 13:13:19 -0700 Subject: [PATCH 55/98] Restores `IS_RANDO` default for the "Always Win Dampe Digging Game" enhancement and changes the tooltip to reflect the default status rather than the forced on status. (#5788) --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 4 ++-- soh/soh/SohGui/SohMenuEnhancements.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index dcac45c88..793583698 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -715,14 +715,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; case VB_BE_VALID_GRAVEDIGGING_SPOT: - if (CVarGetInteger(CVAR_ENHANCEMENT("DampeWin"), 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("DampeWin"), IS_RANDO)) { EnTk* enTk = va_arg(args, EnTk*); enTk->validDigHere = true; *should = true; } break; case VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE: - if (CVarGetInteger(CVAR_ENHANCEMENT("DampeWin"), 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("DampeWin"), IS_RANDO)) { EnTk* enTk = va_arg(args, EnTk*); enTk->currentReward = 3; *should = true; diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index dd965be0a..87eb881cb 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1281,7 +1281,7 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("DampeWin")) .Options(CheckboxOptions().Tooltip( "Always win the Heart Piece/Purple Rupee on the first dig in Dampe's Grave Digging game. " - "In a Randomizer file, this is always enabled.")); + "In a Randomizer file, this defaults to on if this enhancement has never been changed.")); AddWidget(path, "All Dogs are Richard", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("AllDogsRichard")) .Options(CheckboxOptions().Tooltip("All dogs can be traded in and will count as Richard.")); From 911c107b6ecb1e7596f5420fc4bd260890760fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 18 Sep 2025 00:24:52 +0000 Subject: [PATCH 56/98] saves: use single white space when formatting (#5791) this halves size of rando saves --- soh/soh/SaveManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 05b85e69a..aa8481629 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1046,12 +1046,12 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se #if defined(__SWITCH__) || defined(__WIIU__) FILE* w = fopen(tempFile.c_str(), "w"); - std::string json_string = saveBlock.dump(4); + std::string json_string = saveBlock.dump(1); fwrite(json_string.c_str(), sizeof(char), json_string.length(), w); fclose(w); #else std::ofstream output(tempFile); - output << std::setw(4) << saveBlock << std::endl; + output << std::setw(1) << saveBlock << std::endl; output.close(); #endif @@ -1112,7 +1112,7 @@ void SaveManager::SaveGlobal() { const std::filesystem::path sGlobalPath = sSavePath / std::string("global.sav"); std::ofstream output(sGlobalPath); - output << std::setw(4) << globalBlock << std::endl; + output << std::setw(1) << globalBlock << std::endl; } void SaveManager::LoadFile(int fileNum) { From 4bc2bb559205c0a68b082ddcb18e79ee09e769f9 Mon Sep 17 00:00:00 2001 From: Patrick12115 <115201185+Patrick12115@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:39:30 -0400 Subject: [PATCH 57/98] Wiggle (#5794) --- soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index c94c68511..eccfc3dc3 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -43,7 +43,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { objComb->unk_1B0 -= 50; const auto beehiveIdentity = ObjectExtension::GetInstance().Get(&objComb->actor); - if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity == nullptr && + if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity != nullptr && !Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) { if (objComb->unk_1B0 <= -5000) { objComb->unk_1B0 = 1500; @@ -82,9 +82,11 @@ void ObjComb_RandomizerInit(void* actor) { void ObjComb_RandomizerUpdate(void* actor) { ObjComb* combActor = reinterpret_cast(actor); + PlayState* play = gPlayState; + combActor->unk_1B2 += 0x2EE0; + combActor->actionFunc(combActor, play); combActor->actor.shape.rot.x = - static_cast(Math_SinS(combActor->unk_1B2)) * CLAMP_MIN(combActor->unk_1B0, 0) + - combActor->actor.home.rot.x; + Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x; } void RegisterShuffleBeehives() { From 7cce840472082cdfadeb2994a6cff68af7d971be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 18 Sep 2025 00:40:06 +0000 Subject: [PATCH 58/98] rando: fix bug where Mido blocks path to Deku Tree when Closed Forest off but Zelda's Letter not skipped (#5785) --- soh/soh/Enhancements/randomizer/savefile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 51101f6fa..ade5dd163 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -243,6 +243,11 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); + if (Randomizer_GetSettingValue(RSK_FOREST) == RO_CLOSED_FOREST_OFF) { + Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); + } + // Go away Ruto (Water Temple first cutscene). gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); From b944d01b12aacf5e06226538fac2a4badb176359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 18 Sep 2025 20:29:21 +0000 Subject: [PATCH 59/98] atomic saving (#5792) prefer rename to copy/delete, this avoids issues with partial writes --- soh/soh/SaveManager.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index aa8481629..d15c01086 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1055,19 +1055,17 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se output.close(); #endif +#if defined(__SWITCH__) || defined(__WIIU__) if (std::filesystem::exists(fileName)) { std::filesystem::remove(fileName); } - -#if defined(__SWITCH__) || defined(__WIIU__) copy_file(tempFile.c_str(), fileName.c_str()); -#else - std::filesystem::copy_file(tempFile, fileName); -#endif - if (std::filesystem::exists(tempFile)) { std::filesystem::remove(tempFile); } +#else + std::filesystem::rename(tempFile, fileName); +#endif delete saveContext; InitMeta(fileNum); @@ -1164,15 +1162,12 @@ void SaveManager::LoadFile(int fileNum) { std::string newFileName = Ship::Context::GetPathRelativeToAppDirectory("Save") + ("/file" + std::to_string(fileNum + 1) + "-" + std::to_string(GetUnixTimestamp()) + ".bak"); - std::filesystem::path newFile(newFileName); - #if defined(__SWITCH__) || defined(__WIIU__) - copy_file(fileName.c_str(), newFile.c_str()); -#else - std::filesystem::copy_file(fileName, newFile); -#endif - + copy_file(fileName.c_str(), newFileName.c_str()); std::filesystem::remove(fileName); +#else + std::filesystem::rename(fileName, newFileName); +#endif SohGui::RegisterPopup( "Outdated Randomizer Save", "The SoH version in the file in slot " + std::to_string(fileNum + 1) + @@ -1229,16 +1224,15 @@ void SaveManager::LoadFile(int fileNum) { GameInteractor::Instance->ExecuteHooks(fileNum); } catch (const std::exception& e) { input.close(); - std::filesystem::path newFile( + std::string newFileName = Ship::Context::GetPathRelativeToAppDirectory("Save") + - ("/file" + std::to_string(fileNum + 1) + "-" + std::to_string(GetUnixTimestamp()) + ".bak")); + ("/file" + std::to_string(fileNum + 1) + "-" + std::to_string(GetUnixTimestamp()) + ".bak"); #if defined(__SWITCH__) || defined(__WIIU__) - copy_file(fileName.c_str(), newFile.c_str()); -#else - std::filesystem::copy_file(fileName, newFile); -#endif - + copy_file(fileName.c_str(), newFileName.c_str()); std::filesystem::remove(fileName); +#else + std::filesystem::rename(fileName, newFileName); +#endif SohGui::RegisterPopup("Error loading save file", "A problem occurred loading the save in slot " + std::to_string(fileNum + 1) + ".\nSave file corruption is suspected.\n" + From 577c5639df7d0d92f8fb751f3fefa7e4ed97f264 Mon Sep 17 00:00:00 2001 From: "enzu.ru" Date: Thu, 18 Sep 2025 13:29:35 -0700 Subject: [PATCH 60/98] Improve Nix support (#5777) * Fix FindOpusFile NixOS bug * better documentation --- CMake/FindOpusFile.cmake | 8 +++++ docs/BUILDING.md | 72 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CMake/FindOpusFile.cmake b/CMake/FindOpusFile.cmake index ed3b4b7ba..c7fcd2fb1 100644 --- a/CMake/FindOpusFile.cmake +++ b/CMake/FindOpusFile.cmake @@ -6,9 +6,16 @@ # OPUSFILE_LIBRARY - Path to the opusfile library # OPUSFILE_LIBRARIES - Full list of libraries to link (opusfile, opus, ogg) +# Use pkg-config to find opusfile if available +find_package(PkgConf) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_OPUSFILE QUIET opusfile) +endif() + # Search for the OpusFile header find_path(OPUSFILE_INCLUDE_DIR NAMES opusfile.h + HINTS ${PC_OPUSFILE_INCLUDE_DIRS} PATHS /usr/include/opus /usr/local/include/opus /opt/local/include/opus /opt/homebrew/include/opus DOC "Directory where opusfile.h is located" ) @@ -16,6 +23,7 @@ find_path(OPUSFILE_INCLUDE_DIR # Search for the OpusFile library find_library(OPUSFILE_LIBRARY NAMES opusfile + HINTS ${PC_OPUSFILE_LIBRARY_DIRS} DOC "Path to the libopusfile library" ) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index f8347b9b6..72a1863b0 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -119,6 +119,72 @@ zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel lib # or using clang zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel ``` +#### Nix +You can use a `flake.nix` file to instantly setup a development environment using [Nix](https://nixos.org/). Write this `flake.nix` file in the root directory: + +```nix +{ + description = "Shipwright development environment"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + # Build tools + clang + git + cmake + ninja + lsb-release + pkg-config + + # SDL2 libraries + SDL2 + SDL2.dev + SDL2_net + + # Other libraries + libpng + libzip + nlohmann_json + tinyxml-2 + spdlog + libGL + libGL.dev + bzip2 + + # X11 libraries + xorg.libX11 + + # Audio libraries + libogg + libogg.dev + libvorbis + libvorbis.dev + libopus + libopus.dev + opusfile + opusfile.dev + ]; + shellHook = '' + echo "Shipwright development environment loaded" + echo "Available tools: clang, git, cmake, ninja" + ''; + }; + }); +} +``` + +Now type `nix develop` and you will be dropped into a shell with all dependencies, ensuring that all build commands work. ### Build @@ -231,7 +297,7 @@ cmake --build build-cmake --target ExtractAssetHeaders ## Switch 1. Requires that your build machine is setup with the tools necessary for your platform above -2. Requires that you have the switch build tools installed +2. Requires that you have the switch build tools installed 3. Clone the Ship of Harkinian repository 4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice @@ -252,7 +318,7 @@ cmake --build build-switch --target soh_nro ## Wii U 1. Requires that your build machine is setup with the tools necessary for your platform above -2. Requires that you have the Wii U build tools installed +2. Requires that you have the Wii U build tools installed 3. Clone the Ship of Harkinian repository 4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice @@ -265,7 +331,7 @@ cmake --build build-cmake --target ExtractAssets # Setup cmake project for building for Wii U cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) # Build project and generate rpx -cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb) +cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb) # Now you can run the executable in ./build-wiiu/soh/soh.rpx or the Wii U Homebrew Bundle in ./build-wiiu/soh/soh.wuhb # To develop the project open the repository in VSCode (or your preferred editor) From 8e15cefe2b6b3882338d82fd4fa4d29c30bf13fe Mon Sep 17 00:00:00 2001 From: William Casarin Date: Thu, 18 Sep 2025 13:34:41 -0700 Subject: [PATCH 61/98] dev-tools: add bit label on flags table (#5658) * build: add -Wformat-security On some distros format-security is turned on to detect possible issues with non-string literals as format strings Let's explicitly turn it on and fix the ImgUi text formatting to avoid compile issues on those platforms Signed-off-by: William Casarin * save-editor: add flag table bit index labels Signed-off-by: William Casarin --------- Signed-off-by: William Casarin --- soh/soh/Enhancements/debugger/debugSaveEditor.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 7b514a16c..463f900e0 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -572,7 +572,9 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl PopStyleCheckbox(); if (ImGui::IsItemHovered() && hasDescription) { ImGui::BeginTooltip(); - ImGui::Text("%s", UIWidgets::WrappedText(flagTable.flagDescriptions.at(row * 16 + flagIndex), 60).c_str()); + uint16_t index = row * 16 + flagIndex; + const char* desc = flagTable.flagDescriptions.at(index); + ImGui::Text("0x%02X: %s", index, UIWidgets::WrappedText(desc, 60).c_str()); ImGui::EndTooltip(); } ImGui::PopID(); @@ -930,7 +932,15 @@ void DrawFlagsTab() { for (int j = 0; j < flagTable.size + 1; j++) { DrawGroupWithBorder( [&]() { - ImGui::Text("%s", fmt::format("{:<2x}", j).c_str()); + if (j == 0) { + for (int k = 0xF; k >= 0; k--) { + ImGui::SameLine(37.5 + ((0xF - k) * 33.8)); + ImGui::Text("%X", k); + } + } + + ImGui::Text("%s", fmt::format("{:<2X}", j).c_str()); + switch (flagTable.flagTableType) { case EVENT_CHECK_INF: DrawFlagTableArray16(flagTable, j, gSaveContext.eventChkInf[j]); From eeb5a809ae4cc85ed1c27aea11bc68ad72949895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 19 Sep 2025 02:58:30 +0000 Subject: [PATCH 62/98] Rando: option for Mido to hint location of Kokiri Sword (#5724) * Rando: option for Mido to hint location of Kokiri Sword also fix bug where Mido blocks path to Deku Tree when Closed Forest off but Zelda's Letter not skipped * french Co-authored-by: PurpleHato --------- Co-authored-by: PurpleHato --- .../custom-message/CustomMessageTypes.h | 4 +++ .../randomizer/3drando/hint_list.cpp | 5 +++ .../randomizer/option_descriptions.cpp | 1 + .../Enhancements/randomizer/randomizerTypes.h | 3 ++ soh/soh/Enhancements/randomizer/settings.cpp | 35 ++++++++++++++----- .../Enhancements/randomizer/static_data.cpp | 2 ++ soh/soh/OTRGlobals.cpp | 4 +++ 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 635fbcd7d..1b04e5780 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -121,6 +121,10 @@ typedef enum { TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890, TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891, TEXT_WARP_PRELUDE_OF_LIGHT = 0x0892, + TEXT_MIDO_HOME_AFTER_ZELDAS_LETTER = 0x1028, + TEXT_MIDO_SPEAK_TO_MIDO_FIRST_TIME = 0x102F, + TEXT_MIDO_SPEAK_TO_MIDO_AGAIN = 0x1030, + TEXT_MIDO_HOME_BEFORE_ZELDAS_LETTER = 0x1046, TEXT_SCRUB_POH = 0x10A2, TEXT_SARIA_SFM = 0x10AD, TEXT_SCRUB_STICK_UPGRADE = 0x10DC, diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 21891ff81..0c9e2cf70 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2257,6 +2257,11 @@ void StaticData::HintTable_Init() { /*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#.^Tu devrais aller y jeter un coup d'oeil, @!\x0B", {QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE)); + hintTextTable[RHT_MIDO_HINT] = HintText(CustomMessage("You'll never find the #Kokiri Sword# I hid in #[[1]]#!", + /*german*/ TODO_TRANSLATE, + /*french*/ "Pfeuuh! Tu n'trouveras jamais l'#Epée Kokiri# que j'ai cachée dans #[[1]]#!", + {QM_GREEN, QM_RED})); + hintTextTable[RHT_LOACH_HINT] = HintText(CustomMessage("What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that I'll give my %g[[1]]%w to anyone who catches it. Seriously!", /*german*/ "Was?^Du willst etwas über die&%rhylianische Forelle%w wissen?&Es ist ein riesiger Fisch,&der unfassbar selten ist!^Wenn Du mir eine bringst, |springt|springen| für Dich&%g[[1]]%w dabei raus.&Ganz im Ernst!", /*french*/ "Quoi?&Tu veux en savoir plus sur le&%rBrochet d'Hyrule%w?^C'est un gros poisson, mais il&est si rare que je donne&%g[[1]]%w&à celui qui l'attrape.^Ouais, j'suis sérieux!", diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 50d11d9b2..bd19b3dcb 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -684,6 +684,7 @@ void Settings::CreateOptionDescriptions() { "tell you what's the reward for the Hyrule Loach."; mOptionDescriptions[RSK_SARIA_HINT] = "Talking to Saria either in person or through Saria's Song will tell you the " "location of a progressive magic meter."; + mOptionDescriptions[RSK_MIDO_HINT] = "Talking to Mido as child will tell you the location of the Kokiri Sword."; mOptionDescriptions[RSK_FISHING_POLE_HINT] = "Talking to the fishing pond owner without the fishing pole will tell you its location."; mOptionDescriptions[RSK_OOT_HINT] = diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index ab9b6edbc..1c6ac5e82 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4111,6 +4111,7 @@ typedef enum { RH_ALTAR_CHILD, RH_ALTAR_ADULT, RH_SARIA_HINT, + RH_MIDO_HINT, RH_LOACH_HINT, RH_FISHING_POLE, RH_MINUET_WARP_LOC, @@ -5378,6 +5379,7 @@ typedef enum { RHT_GREG_HINT, RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT, + RHT_MIDO_HINT, RHT_LOACH_HINT, RHT_FISHING_POLE_HINT, // Static Entrance Hints @@ -5818,6 +5820,7 @@ typedef enum { RSK_GREG_HINT, RSK_LOACH_HINT, RSK_SARIA_HINT, + RSK_MIDO_HINT, RSK_FROGS_HINT, RSK_OOT_HINT, RSK_KAK_10_SKULLS_HINT, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index e46cc4eee..7872718d6 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -281,6 +281,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_GREG_HINT, "Greg the Green Rupee Hint", CVAR_RANDOMIZER_SETTING("GregHint"), mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE); OPT_BOOL(RSK_LOACH_HINT, "Hyrule Loach Hint", CVAR_RANDOMIZER_SETTING("LoachHint"), mOptionDescriptions[RSK_LOACH_HINT], IMFLAG_NONE); OPT_BOOL(RSK_SARIA_HINT, "Saria's Hint", CVAR_RANDOMIZER_SETTING("SariaHint"), mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE); + OPT_BOOL(RSK_MIDO_HINT, "Mido's Hint", CVAR_RANDOMIZER_SETTING("MidoHint"), mOptionDescriptions[RSK_MIDO_HINT], IMFLAG_NONE); OPT_BOOL(RSK_FISHING_POLE_HINT, "Fishing Pole Hint", CVAR_RANDOMIZER_SETTING("FishingPoleHint"), mOptionDescriptions[RSK_FISHING_POLE_HINT], IMFLAG_NONE); OPT_BOOL(RSK_FROGS_HINT, "Frog Ocarina Game Hint", CVAR_RANDOMIZER_SETTING("FrogsHint"), mOptionDescriptions[RSK_FROGS_HINT], IMFLAG_NONE); OPT_BOOL(RSK_OOT_HINT, "Ocarina of Time Hint", CVAR_RANDOMIZER_SETTING("OoTHint"), mOptionDescriptions[RSK_OOT_HINT], IMFLAG_NONE); @@ -1352,14 +1353,31 @@ void Settings::CreateOptions() { WidgetContainerType::SECTION); mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup( "Extra Hints", - { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], &mOptions[RSK_SHEIK_LA_HINT], - &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], - &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], - &mOptions[RSK_BIGGORON_HINT], &mOptions[RSK_BIG_POES_HINT], &mOptions[RSK_CHICKENS_HINT], - &mOptions[RSK_MALON_HINT], &mOptions[RSK_HBA_HINT], &mOptions[RSK_FISHING_POLE_HINT], - &mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_MERCHANT_TEXT_HINT], - &mOptions[RSK_KAK_10_SKULLS_HINT], &mOptions[RSK_KAK_20_SKULLS_HINT], &mOptions[RSK_KAK_30_SKULLS_HINT], - &mOptions[RSK_KAK_40_SKULLS_HINT], &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], + { &mOptions[RSK_TOT_ALTAR_HINT], + &mOptions[RSK_GANONDORF_HINT], + &mOptions[RSK_SHEIK_LA_HINT], + &mOptions[RSK_DAMPES_DIARY_HINT], + &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], + &mOptions[RSK_SARIA_HINT], + &mOptions[RSK_MIDO_HINT], + &mOptions[RSK_FROGS_HINT], + &mOptions[RSK_OOT_HINT], + &mOptions[RSK_BIGGORON_HINT], + &mOptions[RSK_BIG_POES_HINT], + &mOptions[RSK_CHICKENS_HINT], + &mOptions[RSK_MALON_HINT], + &mOptions[RSK_HBA_HINT], + &mOptions[RSK_FISHING_POLE_HINT], + &mOptions[RSK_WARP_SONG_HINTS], + &mOptions[RSK_SCRUB_TEXT_HINT], + &mOptions[RSK_MERCHANT_TEXT_HINT], + &mOptions[RSK_KAK_10_SKULLS_HINT], + &mOptions[RSK_KAK_20_SKULLS_HINT], + &mOptions[RSK_KAK_30_SKULLS_HINT], + &mOptions[RSK_KAK_40_SKULLS_HINT], + &mOptions[RSK_KAK_50_SKULLS_HINT], + &mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_MASK_SHOP_HINT] }, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = @@ -1619,6 +1637,7 @@ void Settings::CreateOptions() { &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], + &mOptions[RSK_MIDO_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], &mOptions[RSK_WARP_SONG_HINTS], diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index 448b33819..1becef894 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -71,6 +71,7 @@ std::unordered_map StaticData::hintNames = { { RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child") }, { RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult") }, { RH_SARIA_HINT, CustomMessage("Saria's Magic Hint") }, + { RH_MIDO_HINT, CustomMessage("Mido's Kokiri Sword Hint") }, { RH_LOACH_HINT, CustomMessage("Loach Hint") }, { RH_FISHING_POLE, CustomMessage("Fishing Pole Hint") }, { RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination") }, @@ -194,6 +195,7 @@ std::unordered_map StaticData::staticHintInfoMap {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})}, {RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)}, + {RH_MIDO_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_MIDO_HINT}, RSK_MIDO_HINT, true, {}, {RG_KOKIRI_SWORD}, {}, true)}, {RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})}, {RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)}, {RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})}, diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index f35fcaaf1..d306ce228 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2620,6 +2620,10 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if ((textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER) && ctx->GetOption(RSK_SARIA_HINT)) { messageEntry = ctx->GetHint(RH_SARIA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1); + } else if ((textId == TEXT_MIDO_SPEAK_TO_MIDO_FIRST_TIME || textId == TEXT_MIDO_SPEAK_TO_MIDO_AGAIN || + textId == TEXT_MIDO_HOME_AFTER_ZELDAS_LETTER || textId == TEXT_MIDO_HOME_BEFORE_ZELDAS_LETTER) && + ctx->GetOption(RSK_MIDO_HINT)) { + messageEntry = ctx->GetHint(RH_MIDO_HINT)->GetHintMessage(MF_AUTO_FORMAT); } else if (ctx->GetOption(RSK_BIGGORON_HINT) && (textId == TEXT_BIGGORON_BETTER_AT_SMITHING || textId == TEXT_BIGGORON_WAITING_FOR_YOU || textId == TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS || textId == TEXT_BIGGORON_I_MAAAADE_THISSSS)) { From a576bffe3aa80fc65ff86e2158e992451de78a00 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Sat, 20 Sep 2025 02:31:20 +0200 Subject: [PATCH 63/98] Additions for the German translation in hint_list.cpp (#5803) --- soh/soh/Enhancements/randomizer/3drando/hint_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 0c9e2cf70..598940082 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2258,7 +2258,7 @@ void StaticData::HintTable_Init() { {QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE)); hintTextTable[RHT_MIDO_HINT] = HintText(CustomMessage("You'll never find the #Kokiri Sword# I hid in #[[1]]#!", - /*german*/ TODO_TRANSLATE, + /*german*/ "Du wirst nie das #Kokiri-Schwert# finden, das ich in #[[1]]# versteckt habe!", /*french*/ "Pfeuuh! Tu n'trouveras jamais l'#Epée Kokiri# que j'ai cachée dans #[[1]]#!", {QM_GREEN, QM_RED})); From b30c4ab7da6579d3180cd727a494f28646f83658 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Thu, 25 Sep 2025 08:28:23 -0700 Subject: [PATCH 64/98] Fix issues arising from the Search Widgets PR. (#5813) --- .../randomizer/randomizer_check_tracker.cpp | 41 ++++++++++++++++++- .../randomizer/randomizer_item_tracker.cpp | 2 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 1859ed473..ee1a8d9c0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -949,6 +949,43 @@ void SetAreaSpoiled(RandomizerCheckArea rcArea) { } void CheckTrackerWindow::DrawElement() { + Color_Background = CVarGetColor(CVAR_TRACKER_CHECK("BgColor.Value"), Color_Bg_Default); + Color_Area_Incomplete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); + Color_Area_Incomplete_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); + Color_Area_Complete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); + Color_Area_Complete_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); + Color_Unchecked_Main = CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.MainColor.Value"), Color_Main_Default); + Color_Unchecked_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.ExtraColor.Value"), Color_Unchecked_Extra_Default); + Color_Skipped_Main = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.MainColor.Value"), Color_Main_Default); + Color_Skipped_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.ExtraColor.Value"), Color_Skipped_Extra_Default); + Color_Seen_Main = CVarGetColor(CVAR_TRACKER_CHECK("Seen.MainColor.Value"), Color_Main_Default); + Color_Seen_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Seen.ExtraColor.Value"), Color_Seen_Extra_Default); + Color_Hinted_Main = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.MainColor.Value"), Color_Main_Default); + Color_Hinted_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.ExtraColor.Value"), Color_Hinted_Extra_Default); + Color_Collected_Main = CVarGetColor(CVAR_TRACKER_CHECK("Collected.MainColor.Value"), Color_Main_Default); + Color_Collected_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("Collected.ExtraColor.Value"), Color_Collected_Extra_Default); + Color_Scummed_Main = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.MainColor.Value"), Color_Main_Default); + Color_Scummed_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.ExtraColor.Value"), Color_Scummed_Extra_Default); + Color_Saved_Main = CVarGetColor(CVAR_TRACKER_CHECK("Saved.MainColor.Value"), Color_Main_Default); + Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor.Value"), Color_Saved_Extra_Default); + hideUnchecked = CVarGetInteger(CVAR_TRACKER_CHECK("Unchecked.Hide"), 0); + hideScummed = CVarGetInteger(CVAR_TRACKER_CHECK("Scummed.Hide"), 0); + hideSeen = CVarGetInteger(CVAR_TRACKER_CHECK("Seen.Hide"), 0); + hideSkipped = CVarGetInteger(CVAR_TRACKER_CHECK("Skipped.Hide"), 0); + hideSaved = CVarGetInteger(CVAR_TRACKER_CHECK("Saved.Hide"), 0); + hideCollected = CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0); + showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); + mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0); + showLogicTooltip = CVarGetInteger(CVAR_TRACKER_CHECK("ShowLogic"), 0); + enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); + onlyShowAvailable = CVarGetInteger(CVAR_TRACKER_CHECK("OnlyShowAvailable"), 0); + + hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); + alwaysShowGS = CVarGetInteger(CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), 0); if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { if (CVarGetInteger(CVAR_TRACKER_CHECK("ShowOnlyPaused"), 0) && (gPlayState == nullptr || gPlayState->pauseCtx.state == 0)) { @@ -2188,13 +2225,13 @@ void CheckTrackerWindow::UpdateElement() { void RegisterCheckTrackerWidgets() { backgroundColorWidget = { .name = "Background Color##CheckTrackerBgColor", .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; - backgroundColorWidget.CVar(CVAR_TRACKER_ITEM("BgColor")) + backgroundColorWidget.CVar(CVAR_TRACKER_CHECK("BgColor")) .Options( ColorPickerOptions().Color(THEME_COLOR).DefaultValue(Color_Bg_Default).UseAlpha().ShowReset().ShowRandom()); SohGui::mSohMenu->AddSearchWidget({ backgroundColorWidget, "Randomizer", "Check Tracker", "General Settings" }); windowTypeWidget = { .name = "Window Type", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; - windowTypeWidget.CVar(CVAR_TRACKER_ITEM("WindowType")) + windowTypeWidget.CVar(CVAR_TRACKER_CHECK("WindowType")) .Options(ComboboxOptions() .DefaultIndex(TRACKER_WINDOW_WINDOW) .ComponentAlignment(ComponentAlignments::Right) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 1e677df1a..9e5a9be89 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -2031,7 +2031,7 @@ void RegisterItemTrackerWidgets() { SohGui::mSohMenu->AddSearchWidget({ gregTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); bossSoulsTracking = { .name = "Boss Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; - bossSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.Greg")) + bossSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.BossSouls")) .Options(ComboboxOptions() .DefaultIndex(SECTION_DISPLAY_HIDDEN) .ComponentAlignment(ComponentAlignments::Right) From c7975898a57666915eb59d21ceaebdd5dcd9eec7 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:24:51 +0100 Subject: [PATCH 65/98] Apply price logic to bean salesman (#5811) * apply price logic to bean salesman * clang --- soh/soh/Enhancements/randomizer/location_access.cpp | 3 ++- .../randomizer/location_access/overworld/zoras_river.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index f075e1b0c..009aaaf80 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -106,7 +106,8 @@ bool LocationAccess::CanBuy(bool calculatingAvailableChecks) const { const auto& loc = Rando::StaticData::GetLocation(location); const auto& itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(location); - if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT) { + if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT || + location == RC_ZR_MAGIC_BEAN_SALESMAN) { // Checks should only be identified while playing if (calculatingAvailableChecks && itemLoc->GetCheckStatus() != RCSHOW_IDENTIFIED) { return CanBuyAnother(GetMinimumPrice(loc)); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 5473ee2ca..f461a1dc1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -34,7 +34,7 @@ void RegionTable_Init_ZoraRiver() { EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), }, { //Locations - LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->IsChild), LOCATION(RC_ZR_FROGS_OCARINA_GAME, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_SARIAS_SONG) && logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_IN_THE_RAIN, logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_FROGS_ZELDAS_LULLABY, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY)), From 4b9c949428bd89def55102393fae2375e50a6829 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:50:16 +0200 Subject: [PATCH 66/98] Fix dark link ice floors (#5808) --- soh/soh/Enhancements/enemyrandomizer.cpp | 19 +++++++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 17 +++++++++++++++ .../actors/ovl_player_actor/z_player.c | 21 ++++++++++++++----- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index 11f024226..2913e06db 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -619,6 +619,7 @@ void FixClubMoblinScale(void* ptr) { void RegisterEnemyRandomizer() { COND_ID_HOOK(OnActorInit, ACTOR_EN_MB, CVAR_ENEMY_RANDOMIZER_VALUE, FixClubMoblinScale); + // prevent dark link from triggering a voidout COND_VB_SHOULD(VB_TRIGGER_VOIDOUT, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, { Actor* actor = va_arg(args, Actor*); @@ -647,6 +648,24 @@ void RegisterEnemyRandomizer() { } }); + // prevent dark link from interfering with ice floors + COND_VB_SHOULD(VB_SET_STATIC_PREV_FLOOR_TYPE, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, { + Player* playerOrDarkLink = va_arg(args, Player*); + + if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { + *should = false; + } + }); + + // prevent dark link from interfering with ice floors + COND_VB_SHOULD(VB_SET_STATIC_FLOOR_TYPE, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, { + Player* playerOrDarkLink = va_arg(args, Player*); + + if (playerOrDarkLink->actor.id != ACTOR_PLAYER) { + *should = false; + } + }); + // prevent dark link from being grabbed by like likes and therefore grabbing the player COND_VB_SHOULD(VB_LIKE_LIKE_GRAB_PLAYER, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, { EnRr* likeLike = va_arg(args, EnRr*); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 7e517155b..6eada52f6 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2239,6 +2239,7 @@ typedef enum { // #### `args` // - `*PlayState` VB_SHOW_GAMEPLAY_TIMER, + // (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open && // this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100 // ``` @@ -2253,6 +2254,22 @@ typedef enum { // #### `args` // - `*DoorShutter` VB_BE_NEAR_DOOR_SHUTTER, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*Player` + VB_SET_STATIC_PREV_FLOOR_TYPE, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*Player` + VB_SET_STATIC_FLOOR_TYPE, } GIVanillaBehavior; #endif 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 3571ca135..7da8447c0 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5796,7 +5796,10 @@ void func_8083AA10(Player* this, PlayState* play) { if (this->hoverBootsTimer != 0) { this->actor.velocity.y = 1.0f; - sPrevFloorProperty = 9; + + if (GameInteractor_Should(VB_SET_STATIC_PREV_FLOOR_TYPE, true, this)) { + sPrevFloorProperty = 9; + } return; } @@ -11151,7 +11154,9 @@ s32 Player_UpdateHoverBoots(Player* this) { } return false; } else { - sFloorType = 0; + if (GameInteractor_Should(VB_SET_STATIC_FLOOR_TYPE, true, this)) { + sFloorType = 0; + } this->floorPitch = this->floorPitchAlt = sFloorShapePitch = 0; return true; @@ -11182,7 +11187,9 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { f32 ceilingCheckHeight; u32 flags; - sPrevFloorProperty = this->floorProperty; + if (GameInteractor_Should(VB_SET_STATIC_PREV_FLOOR_TYPE, true, this)) { + sPrevFloorProperty = this->floorProperty; + } #define vWallCheckRadius float0 #define vWallCheckHeight float1 @@ -11453,7 +11460,9 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { } if (this->actor.bgCheckFlags & 1) { - sFloorType = func_80041D4C(&play->colCtx, floorPoly, this->actor.floorBgId); + if (GameInteractor_Should(VB_SET_STATIC_FLOOR_TYPE, true, this)) { + sFloorType = func_80041D4C(&play->colCtx, floorPoly, this->actor.floorBgId); + } if (!Player_UpdateHoverBoots(this)) { f32 floorPolyNormalX; @@ -12100,7 +12109,9 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { Actor_UpdatePos(&this->actor); Player_ProcessSceneCollision(play, this); } else { - sFloorType = 0; + if (GameInteractor_Should(VB_SET_STATIC_FLOOR_TYPE, true, this)) { + sFloorType = 0; + } this->floorProperty = 0; if (!(this->stateFlags1 & PLAYER_STATE1_LOADING) && (this->stateFlags1 & PLAYER_STATE1_ON_HORSE)) { From 14d269d99e752411ab231122251a573ad75b2a7d Mon Sep 17 00:00:00 2001 From: Spodi Date: Fri, 26 Sep 2025 16:50:24 +0200 Subject: [PATCH 67/98] Fix Multi-Window not checked by default (#5806) * Fix Multi-Window not checked by default Last time i tested with a new config file this was actually on, despite it showing off. So now it shows ON by default :) * clang --- soh/soh/SohGui/SohMenuSettings.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index 768370b85..925ab113d 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -400,8 +400,9 @@ void SohMenu::AddMenuSettings() { .RaceDisable(false) .PreFunc( [](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_MULTI_VIEWPORT).active; }) - .Options(CheckboxOptions().Tooltip( - "Allows multiple windows to be opened at once. Requires a reload to take effect.")); + .Options(CheckboxOptions() + .Tooltip("Allows multiple windows to be opened at once. Requires a reload to take effect.") + .DefaultValue(true)); AddWidget(path, "Texture Filter (Needs reload)", WIDGET_CVAR_COMBOBOX) .CVar(CVAR_TEXTURE_FILTER) .RaceDisable(false) From 207de8f4082d8dd904c3023d6cd5d9624a53ff7c Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Sat, 27 Sep 2025 17:53:20 +0100 Subject: [PATCH 68/98] Remove HasAccessTo and non-self-referncing Here (#5700) * Remove HasEccessTo and non-sel-referncing Here * fix here related logic errors --- .../randomizer/location_access.cpp | 4 - .../Enhancements/randomizer/location_access.h | 1 - .../location_access/dungeons/deku_tree.cpp | 7 +- .../dungeons/dodongos_cavern.cpp | 74 +++++++++++++------ .../location_access/dungeons/fire_temple.cpp | 30 ++++---- .../dungeons/forest_temple.cpp | 44 +++++++---- .../location_access/dungeons/ice_cavern.cpp | 2 +- .../dungeons/spirit_temple.cpp | 4 +- .../location_access/dungeons/water_temple.cpp | 13 ++-- soh/soh/Enhancements/randomizer/logic.cpp | 5 ++ soh/soh/Enhancements/randomizer/logic.h | 5 ++ .../Enhancements/randomizer/randomizerTypes.h | 1 + 12 files changed, 125 insertions(+), 65 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index 009aaaf80..5da8e3f6b 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -763,10 +763,6 @@ bool AdultCanAccess(const RandomizerRegion region) { return areaTable[region].Adult(); } -bool HasAccessTo(const RandomizerRegion region) { - return areaTable[region].HasAccess(); -} - Rando::Context* ctx; std::shared_ptr logic; diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index 5cbc84060..7025898c3 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -231,7 +231,6 @@ bool CanPlantBean(const RandomizerRegion region); bool BothAges(const RandomizerRegion region); bool ChildCanAccess(const RandomizerRegion region); bool AdultCanAccess(const RandomizerRegion region); -bool HasAccessTo(const RandomizerRegion region); namespace Regions { extern void AccessReset(); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 1d98e861a..7a46c2ba5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -91,7 +91,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_LOBBY, []{return true;}), Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), - Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || HasAccessTo(RR_DEKU_TREE_BASEMENT_UPPER);}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->PushedDekuBasementBlock;}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}), }); @@ -162,8 +162,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_UPPER] = Region("Deku Tree Basement Upper", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(&logic->PushedDekuBasementBlock, []{return true;}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index d8e64f996..3a5a850ba 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -27,7 +27,7 @@ void RegionTable_Init_DodongosCavern() { EventAccess(&logic->GossipStoneFairy, []{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), + LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);), LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CallGossipFairy()), LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -37,13 +37,16 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_BEGINNING, []{return true;}), Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, []{return logic->IsAdult;}), Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}), - Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return HasAccessTo(RR_DODONGOS_CAVERN_LOBBY_SWITCH);}), - Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return HasAccessTo(RR_DODONGOS_CAVERN_FAR_BRIDGE);}), - Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, []{return Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HasExplosives();});}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->DCStairsRoomDoor;}), + Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->DCLiftPlatform;}), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->DCEyesLit;}), Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, []{return false;}), }); - areaTable[RR_DODONGOS_CAVERN_LOBBY_SWITCH] = Region("Dodongos Cavern Lobby Switch", SCENE_DODONGOS_CAVERN, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_LOBBY_SWITCH] = Region("Dodongos Cavern Lobby Switch", SCENE_DODONGOS_CAVERN, { + //Events + EventAccess(&logic->DCStairsRoomDoor, []{return true;}), + }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, []{return true;}), Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return true;}), @@ -80,7 +83,10 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return true;}), }); - areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", SCENE_DODONGOS_CAVERN, {}, { + areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", SCENE_DODONGOS_CAVERN, { + //Events + EventAccess(&logic->DCKilledLowerLizalfos, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);}), + }, { //Locations LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, logic->CanBreakPots()), @@ -89,8 +95,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->DCKilledLowerLizalfos;}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->DCKilledLowerLizalfos;}), }); areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Region("Dodongos Cavern Dodongo Room", SCENE_DODONGOS_CAVERN, {}, { @@ -114,7 +120,10 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return true;}), }); - areaTable[RR_DODONGOS_CAVERN_STAIRS_LOWER] = Region("Dodongos Cavern Stairs Lower", SCENE_DODONGOS_CAVERN, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_STAIRS_LOWER] = Region("Dodongos Cavern Stairs Lower", SCENE_DODONGOS_CAVERN, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, ctx->GetTrickOption(RT_DC_VINES_GS) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT)), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, []{return true;}), Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, []{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRS_WITH_BOW) && logic->CanUse(RG_FAIRY_BOW));}), @@ -123,8 +132,8 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Region("Dodongos Cavern Stairs Upper", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HookshotOrBoomerang();}) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack() || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_DC_VINES_GS))), + LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, logic->DCLiftPlatform ? ED_BOOMERANG : ED_LONGSHOT)), + LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_3, logic->CanBreakPots()), @@ -188,11 +197,19 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, true), LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, true), + //This room is in different states based on what entrance you entered by, + //So it's simpler to treat them as separate regions with shared checks in both + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return true;}), - Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->DCKilledLowerLizalfos;}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->DCKilledLowerLizalfos;}), }); areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Region("Dodongos Cavern Second Slingshot Room", SCENE_DODONGOS_CAVERN, {}, { @@ -217,9 +234,13 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return true;}), }); - areaTable[RR_DODONGOS_CAVERN_FAR_BRIDGE] = Region("Dodongos Cavern Far Bridge", SCENE_DODONGOS_CAVERN, {}, { + areaTable[RR_DODONGOS_CAVERN_FAR_BRIDGE] = Region("Dodongos Cavern Far Bridge", SCENE_DODONGOS_CAVERN, { + //Events + EventAccess(&logic->DCEyesLit, []{return logic->HasExplosives();}), + EventAccess(&logic->DCLiftPlatform, []{return true;}), + }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->CanBreakMudWalls();})), + LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, logic->CanBreakMudWalls()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, []{return true;}), @@ -274,7 +295,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->HasItem(RG_GORONS_BRACELET) && logic->TakeDamage();});}), //strength 1 and bunny speed works too Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->IsAdult;}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return Here(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->HasExplosives() || (logic->ClearMQDCUpperLobbyRocks && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->DCEyesLit;}), }); areaTable[RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE] = Region("Dodongos Cavern MQ Gossip Stone", SCENE_DODONGOS_CAVERN, { @@ -293,6 +314,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", SCENE_DODONGOS_CAVERN, { //Events EventAccess(&logic->ClearMQDCUpperLobbyRocks, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), + EventAccess(&logic->DCEyesLit, []{return logic->HasExplosives() || (logic->ClearMQDCUpperLobbyRocks && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));}), }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), @@ -504,7 +526,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM] = Region("Dodongos Cavern Mad Scrub Room", SCENE_DODONGOS_CAVERN, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add - //&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) + //&& (Here(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) LOCATION(RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2, logic->CanCutShrubs()), }, { @@ -514,6 +536,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Region("Dodongos Cavern MQ Behind Mouth", SCENE_DODONGOS_CAVERN, {}, { //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/)), LOCATION(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, logic->CanBreakPots()), @@ -527,9 +550,13 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->IsAdult;}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Region("Dodongos Cavern MQ Back Behind Fire", SCENE_DODONGOS_CAVERN, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Region("Dodongos Cavern MQ Back Behind Fire", SCENE_DODONGOS_CAVERN, { + //Events + EventAccess(&logic->MQDCBehindFireSwitch, []{return logic->CanDetonateBombFlowers();}), + }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, logic->CanCutShrubs()), @@ -537,16 +564,17 @@ void RegionTable_Init_DodongosCavern() { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->CanAttack();}), //There's a trick N64 rolls into the child eyes trick for using armos blow up the bomb flowers when dieing, which would be killing an armos - Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return Here(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, []{return logic->CanDetonateBombFlowers();}) || Here(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->CanAttack();});}), + //RANDOTODO investigate using hovers to go from the door ledge to the block directly + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->MQDCBehindFireSwitch;}), }); areaTable[RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE] = Region("Dodongos Cavern MQ BossArea", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(&logic->MQDCBehindFireSwitch, []{return true/*str0 || logic->CanHitSwitch() || logic->CanDetonateBombFlowers()*/;}), + EventAccess(&logic->FairyPot, []{return true;}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET) || //even if you somehow warp to BACK_BEHIND_FIRE, if you can kill the skull at range, you can get to BEHIND_MOUTH - Here(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/);})), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_GRASS, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 8d8f0ad28..d0c4dfdb7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -38,7 +38,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || Here(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}) || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->HitFireTemplePlatform || logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", SCENE_FIRE_TEMPLE, {}, {}, { @@ -140,8 +140,6 @@ void RegionTable_Init_FireTemple() { }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", SCENE_FIRE_TEMPLE, {}, { - //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;})), }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), @@ -149,7 +147,10 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), }); - areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, true), + }, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}), @@ -260,7 +261,10 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return ctx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Region("Fire Temple Fire Maze Upper", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Region("Fire Temple Fire Maze Upper", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(&logic->HitFireTemplePlatform, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), @@ -275,17 +279,17 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Region("Fire Temple West Central Lower", SCENE_FIRE_TEMPLE, {}, { - //Locations - LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, Here(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER);})), - }, { + areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Region("Fire Temple West Central Lower", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Region("Fire Temple West Central Upper", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Region("Fire Temple West Central Upper", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER)), + }, { //Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return true;}), @@ -382,7 +386,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return Here(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), }); areaTable[RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM] = Region("Fire Temple MQ Iron Knuckle Room", SCENE_FIRE_TEMPLE, { @@ -402,7 +406,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return Here(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), }); areaTable[RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER] = Region("Fire Temple MQ Lower Flare Dancer", SCENE_FIRE_TEMPLE, {}, { @@ -444,7 +448,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return true;}), //Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH, []{return logic->FireTimer() > 32 && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->IsAdult && logic->HitFireTemplePlatform) || (logic->HitFireTemplePlatform && logic->CanUse(RG_HOVER_BOOTS)));}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->HitFireTemplePlatform && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))));}), }); //This room assumes tunic logic is handled on entry. diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index e5c12bc97..8f6fb879f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -81,7 +81,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT) || Here(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HookshotOrBoomerang();})), + LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT)), LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), }, { @@ -89,7 +89,7 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->CanUse(RG_SONG_OF_TIME);}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return true;}), - Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}), + Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), }); @@ -99,8 +99,9 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, true), - LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->HookshotOrBoomerang()), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return true;}), @@ -115,13 +116,13 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT) || HasAccessTo(RR_FOREST_TEMPLE_FALLING_ROOM) || (HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) && logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_OUTDOORS_EAST_GS) && logic->CanUse(RG_BOOMERANG)) || Here(RR_FOREST_TEMPLE_FALLING_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives();})), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_OUTDOORS_EAST_GS) && logic->CanUse(RG_BOOMERANG))), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, []{return true;}), Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, []{return logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT));}), - Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}), + Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, []{return false;}), }); @@ -129,10 +130,14 @@ void RegionTable_Init_ForestTemple() { //Events EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS)), + }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return true;}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return true;}), + Entrance(RR_FOREST_TEMPLE_DRAINED_SEWER, []{return true;}), Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, []{return ctx->GetTrickOption(RT_FOREST_DOORFRAME) && logic->CanJumpslashExceptHammer() && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_SCARECROW);}), }); @@ -147,9 +152,20 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)), - LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), - LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + }, { + //Exits + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return logic->HasItem(RG_BRONZE_SCALE);}), + }); + + areaTable[RR_FOREST_TEMPLE_DRAINED_SEWER] = Region("Forest Temple Drained Well", SCENE_FOREST_TEMPLE, {}, { + //Locations + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, true), + LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return true;}), @@ -265,7 +281,9 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Region("Forest Temple Falling Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives()), + LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return true;}), @@ -361,7 +379,7 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return Here(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->CanKillEnemy(RE_STALFOS);});}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return Here(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return logic->CanKillEnemy(RE_STALFOS);});}), Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return logic->HasItem(RG_GORONS_BRACELET) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), //Assumes RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE access Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 5151377ce..354da0f64 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -85,7 +85,7 @@ void RegionTable_Init_IceCavern() { //the switch for the glass blocking the entrance is linked to the switch that controls the glass around the skulltulla in RR_ICE_CAVERN_MQ_SCARECROW_ROOM //if you clear the ice, you can hit it with a pot from here. Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->BlueFire();}), - Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return Here(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);});}), + Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return Here(RR_ICE_CAVERN_MQ_HUB, []{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);});}), Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, []{return logic->IsAdult && logic->BlueFire();}), Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, []{return logic->BlueFire();}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index f0779358d..2e2edb5b8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -335,7 +335,7 @@ void RegionTable_Init_SpiritTemple() { Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return true;}), //The block here is unusual in that it is a permanent flag, but reset anyway as child. This is because there's a check that would be blocked off by pushing them otherwise //It may be worth considering making this always temp in future so adult doesn't have the same issue - Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS);});}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, []{return logic->CanUse(RG_SILVER_GAUNTLETS);});}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", SCENE_SPIRIT_TEMPLE, {}, { @@ -457,7 +457,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, []{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, []{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", SCENE_SPIRIT_TEMPLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 2efc2fb1e..c87f8bc56 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -85,7 +85,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDERS_LOWER] = Region("Water Temple Boulders Lower", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) || Here(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->IsAdult && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));})), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT)), }, { //Exits Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), @@ -109,7 +109,10 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return true;}), }); - areaTable[RR_WATER_TEMPLE_BOULDERS_UPPER] = Region("Water Temple Boulders Upper", SCENE_WATER_TEMPLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_BOULDERS_UPPER] = Region("Water Temple Boulders Upper", SCENE_WATER_TEMPLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + }, { //Exits Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, []{return true;}), Entrance(RR_WATER_TEMPLE_JETS_ROOM, []{return logic->IsAdult;}), @@ -149,8 +152,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Region("Water Temple Dragon Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || - Here(RR_WATER_TEMPLE_RIVER, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));})), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)))), }, { //Exits Entrance(RR_WATER_TEMPLE_WEST_LOWER, []{return true;}), @@ -262,6 +264,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_RIVER_HEART_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_WATER_TEMPLE_RIVER_HEART_3, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_WATER_TEMPLE_RIVER_HEART_4, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, []{return (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), @@ -746,7 +749,7 @@ void RegionTable_Init_WaterTemple() { { //Exits Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->MQWaterB1Switch && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), - Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->CanUse(RG_FIRE_ARROWS) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->CanUse(RG_LONGSHOT) && Here(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->ScarecrowsSong();})));}) + Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->CanUse(RG_FIRE_ARROWS) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->CanUse(RG_LONGSHOT) && Here(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, []{return logic->ScarecrowsSong();})));}) }); areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE] = Region("Water Temple MQ Triangle Torch Cage", SCENE_WATER_TEMPLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 0779a5aec..34ad7eac5 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2462,6 +2462,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { MQSpirit3SunsEnemies = false; Spirit1FSilverRupees = false; JabuRutoIn1F = false; + DCEyesLit = false; + DCLiftPlatform = false; + DCStairsRoomDoor = false; + DCKilledLowerLizalfos = false; + MQDCBehindFireSwitch = false; CalculatingAvailableChecks = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index aaab8fd4c..550bb99a2 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -135,6 +135,7 @@ class Logic { bool LinksCow = false; bool DeliverLetter = false; bool ClearMQDCUpperLobbyRocks = false; + bool MQDCBehindFireSwitch = false; bool LoweredWaterInsideBotw = false; bool OpenedWestRoomMQBotw = false; bool OpenedMiddleHoleMQBotw = false; @@ -173,6 +174,10 @@ class Logic { bool MQSpirit3SunsEnemies = false; bool Spirit1FSilverRupees = false; bool JabuRutoIn1F = false; + bool DCEyesLit = false; + bool DCLiftPlatform = false; + bool DCStairsRoomDoor = false; + bool DCKilledLowerLizalfos = false; /* --- END OF HELPERS AND LOCATION ACCESS --- */ diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 1c6ac5e82..c619eb186 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -697,6 +697,7 @@ typedef enum { RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, RR_FOREST_TEMPLE_MAP_ROOM, RR_FOREST_TEMPLE_SEWER, + RR_FOREST_TEMPLE_DRAINED_SEWER, RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, RR_FOREST_TEMPLE_FLOORMASTER_ROOM, RR_FOREST_TEMPLE_WEST_CORRIDOR, From 7c8fc85c503994b3b023fd18df9fdd6b214c721f Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 29 Sep 2025 00:08:14 -0400 Subject: [PATCH 69/98] update macports (#5819) --- .github/workflows/generate-builds.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index d68092d99..c1c00ad08 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -113,8 +113,8 @@ jobs: echo "MacPorts already installed" else echo "Installing MacPorts" - wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-14-Sonoma.pkg - sudo installer -pkg ./MacPorts-2.9.3-14-Sonoma.pkg -target / + wget https://github.com/macports/macports-base/releases/download/v2.11.5/MacPorts-2.11.5-14-Sonoma.pkg + sudo installer -pkg ./MacPorts-2.11.5-14-Sonoma.pkg -target / fi echo "/opt/local/bin:/opt/local/sbin" >> "$GITHUB_PATH" - name: Install dependencies From b7de53bf8d7237c4c8ad4cd5329f3b0d62a7b0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 30 Sep 2025 01:51:07 +0000 Subject: [PATCH 70/98] Move logic bools to LogicVal enum (#5727) * Move logic bools to LogicVal enum Tired of seeing logic reset bugs This opens up moving bools to bitset This opens up tracking logic dependencies so events doesn't reevaluate everything This opens up various events reusing logic vals (already done for LOGIC_BLUE_FIRE_ACCESS) * ammo comments, fix magic regression --- soh/soh/Enhancements/randomizer/item.cpp | 4 +- .../randomizer/location_access.cpp | 21 +- .../Enhancements/randomizer/location_access.h | 8 +- .../dungeons/bottom_of_the_well.cpp | 40 ++-- .../location_access/dungeons/deku_tree.cpp | 76 +++--- .../dungeons/dodongos_cavern.cpp | 69 +++--- .../location_access/dungeons/fire_temple.cpp | 78 +++---- .../dungeons/forest_temple.cpp | 108 ++++----- .../dungeons/ganons_castle.cpp | 60 ++--- .../dungeons/gerudo_training_ground.cpp | 28 +-- .../location_access/dungeons/ice_cavern.cpp | 8 +- .../dungeons/jabujabus_belly.cpp | 74 +++--- .../dungeons/shadow_temple.cpp | 26 +-- .../dungeons/spirit_temple.cpp | 40 ++-- .../location_access/dungeons/water_temple.cpp | 150 ++++++------ .../overworld/castle_grounds.cpp | 18 +- .../overworld/death_mountain_crater.cpp | 4 +- .../overworld/death_mountain_trail.cpp | 6 +- .../overworld/desert_colossus.cpp | 6 +- .../overworld/gerudo_fortress.cpp | 14 +- .../overworld/gerudo_valley.cpp | 10 +- .../location_access/overworld/goron_city.cpp | 30 +-- .../location_access/overworld/graveyard.cpp | 14 +- .../overworld/haunted_wasteland.cpp | 6 +- .../overworld/hyrule_field.cpp | 10 +- .../location_access/overworld/kakariko.cpp | 24 +- .../overworld/kokiri_forest.cpp | 22 +- .../location_access/overworld/lake_hylia.cpp | 18 +- .../overworld/lon_lon_ranch.cpp | 4 +- .../location_access/overworld/lost_woods.cpp | 14 +- .../location_access/overworld/market.cpp | 20 +- .../overworld/sacred_forest_meadow.cpp | 4 +- .../overworld/temple_of_time.cpp | 7 +- .../overworld/thieves_hideout.cpp | 24 +- .../overworld/zoras_domain.cpp | 24 +- .../overworld/zoras_fountain.cpp | 4 +- .../location_access/overworld/zoras_river.cpp | 10 +- soh/soh/Enhancements/randomizer/logic.cpp | 220 ++++-------------- soh/soh/Enhancements/randomizer/logic.h | 155 +----------- .../Enhancements/randomizer/randomizerTypes.h | 117 ++++++++++ 40 files changed, 703 insertions(+), 872 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 71f9fff38..5207b9734 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -52,7 +52,7 @@ void Item::ApplyEffect() const { if (!logic->CalculatingAvailableChecks) { logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true); } - logic->SetInLogic(logicVal, true); + logic->Set(logicVal, true); } void Item::UndoEffect() const { @@ -61,7 +61,7 @@ void Item::UndoEffect() const { if (!logic->CalculatingAvailableChecks) { logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false); } - logic->SetInLogic(logicVal, false); + logic->Set(logicVal, false); } const Text& Item::GetName() const { diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index 5da8e3f6b..0f517aa3f 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -771,10 +771,10 @@ void RegionTable_Init() { ctx = Context::GetInstance().get(); logic = ctx->GetLogic(); // RANDOTODO do not hardcode, instead allow accepting a Logic class somehow grottoEvents = { - EventAccess(&logic->GossipStoneFairy, [] { return logic->CallGossipFairy(); }), - EventAccess(&logic->ButterflyFairy, [] { return logic->CanUse(RG_STICKS); }), - EventAccess(&logic->BugShrub, [] { return logic->CanCutShrubs(); }), - EventAccess(&logic->LoneFish, [] { return true; }), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, [] { return logic->CallGossipFairy(); }), + EventAccess(LOGIC_BUTTERFLY_FAIRY, [] { return logic->CanUse(RG_STICKS); }), + EventAccess(LOGIC_BUG_SHRUB, [] { return logic->CanCutShrubs(); }), + EventAccess(LOGIC_LONE_FISH, [] { return true; }), }; // Clear the array from any previous playthrough attempts. This is important so that // locations which appear in both MQ and Vanilla dungeons don't get set in both areas. @@ -783,12 +783,13 @@ void RegionTable_Init() { // clang-format off areaTable[RR_ROOT] = Region("Root", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, { //Events - EventAccess(&logic->KakarikoVillageGateOpen, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}), - EventAccess(&logic->THCouldFree1TorchCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}), - EventAccess(&logic->THCouldFreeDoubleCellCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), - EventAccess(&logic->TH_CouldFreeDeadEndCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), - EventAccess(&logic->THCouldRescueSlopeCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}),EventAccess(&logic->FreedEpona, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}), + EventAccess(LOGIC_KAKARIKO_GATE_OPEN, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}), + EventAccess(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}), + EventAccess(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), + EventAccess(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), + EventAccess(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}), + EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}), + EventAccess(LOGIC_FREED_EPONA, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}), }, { //Locations LOCATION(RC_LINKS_POCKET, true), diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index 7025898c3..d55928eea 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -22,7 +22,7 @@ class Region; class EventAccess { public: - explicit EventAccess(bool* event_, ConditionFn condition_function_) + explicit EventAccess(LogicVal event_, ConditionFn condition_function_) : event(event_), condition_function(condition_function_) { } @@ -37,15 +37,15 @@ class EventAccess { bool CheckConditionAtAgeTime(bool& age, bool& time); void EventOccurred() { - *event = true; + logic->Set(event, true); } bool GetEvent() const { - return *event; + return logic->Get(event); } private: - bool* event; + LogicVal event; ConditionFn condition_function; }; diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 451989a44..46a89f7af 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -19,25 +19,25 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_PERIMETER] = Region("Bottom of the Well Perimeter", SCENE_BOTTOM_OF_THE_WELL, { //Events - EventAccess(&logic->StickPot, []{return true;}), - EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->LoweredWaterInsideBotw, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_STICK_POT, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), + EventAccess(LOGIC_BOTW_LOWERED_WATER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()), - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw || logic->CanOpenUnderwaterChest()), - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw || logic->CanOpenUnderwaterChest()), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()), LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, logic->CanBreakPots()), - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->LoweredWaterInsideBotw) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->Get(LOGIC_BOTW_LOWERED_WATER)) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}), - Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}), - Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->LoweredWaterInsideBotw && logic->IsChild;}), + Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) && logic->IsChild;}), //Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick //kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64 Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return true;}), @@ -97,8 +97,8 @@ void RegionTable_Init_BottomOfTheWell() { //If the player can voidwarp into one of these rooms they will need splitting up, and Fake walls will need specifying into middle and the rest moved to perimeter areaTable[RR_BOTTOM_OF_THE_WELL_INNER_ROOMS] = Region("Bottom of the Well Inner Rooms", SCENE_BOTTOM_OF_THE_WELL, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), @@ -115,7 +115,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { @@ -192,11 +192,11 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Region("Bottom of the Well MQ Perimeter", SCENE_BOTTOM_OF_THE_WELL, { //Events //technically obsolete due to a wonder item fairy which only needs a projectile, but we don't have an event var for it yet - EventAccess(&logic->FairyPot, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets();}), + EventAccess(LOGIC_FAIRY_POT, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets();}), //It is possible to hit the water switch with a pot from RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, however the hitbox for making it activate is very unintuitive //You have to throw the pot from further back to hit the switch from the front instead of the top, trying to hit the "fingers" directly //This unintuitiveness means it should be a trick. ZL is needed to get a clear path to carry the pot - EventAccess(&logic->LoweredWaterInsideBotw, []{return logic->CanJumpslash() || logic->CanUseProjectile();}), + EventAccess(LOGIC_BOTW_LOWERED_WATER, []{return logic->CanJumpslash() || logic->CanUseProjectile();}), }, { //Locations //Implies CanBreakPots() @@ -207,16 +207,16 @@ void RegionTable_Init_BottomOfTheWell() { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild;}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->LoweredWaterInsideBotw;}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->Get(LOGIC_BOTW_LOWERED_WATER);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH] = Region("Bottom of the Well MQ West Room Switch", SCENE_BOTTOM_OF_THE_WELL, { //Events - EventAccess(&logic->OpenedWestRoomMQBotw, []{return true;}), + EventAccess(LOGIC_BOTW_MQ_OPENED_WEST_ROOM, []{return true;}), }, {}, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash() && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || ctx->GetTrickOption(RT_BOTW_MQ_PITS));}), @@ -231,12 +231,12 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE] = Region("Bottom of the Well MQ Locked Cage", SCENE_BOTTOM_OF_THE_WELL, { //Events - EventAccess(&logic->OpenedMiddleHoleMQBotw, []{return logic->HasExplosives();}), + EventAccess(LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE, []{return logic->HasExplosives();}), }, {}, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}), @@ -268,7 +268,7 @@ void RegionTable_Init_BottomOfTheWell() { //Also you get cheap shotted on entry sometimes. //An MQ lens trick is recommended here, and a review of this room for OHKO logic what that is added is advised. //In the meantime I assume damage taken or the easy answer (nuts) - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->Get(LOGIC_BOTW_MQ_OPENED_WEST_ROOM) && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()), @@ -279,7 +279,7 @@ void RegionTable_Init_BottomOfTheWell() { }, { //Exits //If a relevant trick causes you to be able to warp into here without going through PERIMETER, a new eventAccess will be needed for lowering the gates with ZL - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, []{return logic->OpenedMiddleHoleMQBotw;}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, []{return logic->Get(LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE);}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 7a46c2ba5..7de1c43f8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -18,8 +18,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_LOBBY] = Region("Deku Tree Lobby", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_DEKU_TREE_MAP_CHEST, true), @@ -61,8 +61,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_COMPASS_ROOM] = Region("Deku Tree Compass Room", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_DEKU_TREE_COMPASS_CHEST, true), @@ -78,8 +78,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_LOWER] = Region("Deku Tree Basement Lower", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true), @@ -91,7 +91,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_LOBBY, []{return true;}), Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), - Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->PushedDekuBasementBlock;}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK);}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}), }); @@ -125,8 +125,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_TORCH_ROOM] = Region("Deku Tree Basement Torch Room", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, logic->CanCutShrubs()), @@ -139,8 +139,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_BACK_LOBBY] = Region("Deku Tree Basement Back Lobby", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Location LOCATION(RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, logic->CanCutShrubs()), @@ -162,9 +162,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_UPPER] = Region("Deku Tree Basement Upper", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), - EventAccess(&logic->PushedDekuBasementBlock, []{return true;}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, []{return true;}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}), @@ -192,8 +192,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_1F] = Region("Deku Tree MQ 1F", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}), - EventAccess(&logic->BrokeDeku1FWeb, []{return logic->HasFireSource();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}), + EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return logic->HasFireSource();}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_1, logic->CanCutShrubs()), @@ -209,7 +209,7 @@ void RegionTable_Init_DekuTree() { //Swim is not required because you can jump with enough momentum to hit land. //You even avoid fall damage if you hit the shallow water, though it's obscure knowledge so may be a trick //if it is, then we need a landing room with (IsAdult || HasItem(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement - Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->BrokeDeku1FWeb;}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->Get(LOGIC_DEKU_TREE_1F_BROKE_WEB);}), //is it possible to recoil from here to the ledge with a trick? }); @@ -231,9 +231,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_3F] = Region("Deku Tree MQ 3F", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), - EventAccess(&logic->BrokeDeku1FWeb, []{return true;}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return true;}), }, { //Locations //Implies CanKillEnemy(RE_GOHMA_LARVA) @@ -294,8 +294,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_BASEMENT] = Region("Deku Tree MQ Basement", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), @@ -308,14 +308,14 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();});}), //includes RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM Access, other fire sources clear directly from there - Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->ClearedMQDekuSERoom && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}), - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->PushedDekuBasementBlock || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM) && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS);}), }); areaTable[RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM] = Region("Deku Tree MQ Southeast Room", SCENE_DEKU_TREE, { //Events //Implies CanKillEnemy(RE_GOHMA_LARVA) - EventAccess(&logic->ClearedMQDekuSERoom, []{return logic->CanKillEnemy(RE_MAD_SCRUB);}), + EventAccess(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM, []{return logic->CanKillEnemy(RE_MAD_SCRUB);}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, logic->CanCutShrubs()), @@ -325,13 +325,13 @@ void RegionTable_Init_DekuTree() { }, { //Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->HasFireSource();}), - Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->ClearedMQDekuSERoom;}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM);}), }); areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree MQ Basement Water Room Front", SCENE_DEKU_TREE, { //Events //It's possible to get this with bow if you have move while in first person and one-point skips on, noticeably harder and jankier as child, but that's a trick - EventAccess(&logic->MQDekuWaterRoomTorches, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}), + EventAccess(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true), @@ -346,8 +346,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK] = Region("Deku Tree MQ Basement Water Room Back", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}), - EventAccess(&logic->MQDekuWaterRoomTorches, []{return logic->HasFireSource();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}), + EventAccess(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, []{return logic->HasFireSource();}), }, { //Locations //it blocks the chest while stunned unless you stun it from afar while it's slightly off the ground @@ -356,7 +356,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, logic->CanCutShrubs()), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_SHORT_JUMPSLASH);}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return logic->Get(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES) && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_SHORT_JUMPSLASH);}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield()) || logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)));}), }); @@ -373,8 +373,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM] = Region("Deku Tree MQ Basement Grave Room", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}) + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}) }, { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), @@ -404,7 +404,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Region("Deku Tree MQ Basement Ledge", SCENE_DEKU_TREE, { //Events - EventAccess(&logic->PushedDekuBasementBlock, []{return true;}), + EventAccess(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, []{return true;}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()), @@ -417,7 +417,7 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return true;}), //If strength 0 is shuffled, add hovers or block push to the stick check //recoiling to skip swim is possible, but would be a trick - Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->PushedDekuBasementBlock && */logic->CanUse(RG_STICKS));}) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) && */logic->CanUse(RG_STICKS));}) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), }); areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = Region("Deku Tree MQ Outside Boss Room", SCENE_DEKU_TREE, {}, { @@ -450,11 +450,11 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", SCENE_DEKU_TREE_BOSS, { // Events - EventAccess(&logic->DekuTreeClear, []{return logic->CanKillEnemy(RE_GOHMA);}), + EventAccess(LOGIC_DEKU_TREE_CLEAR, []{return logic->CanKillEnemy(RE_GOHMA);}), }, { // Locations - LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear), - LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_HEART, logic->DekuTreeClear), + LOCATION(RC_QUEEN_GOHMA, logic->Get(LOGIC_DEKU_TREE_CLEAR)), + LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_HEART, logic->Get(LOGIC_DEKU_TREE_CLEAR)), LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, logic->CanCutShrubs()), @@ -466,7 +466,7 @@ void RegionTable_Init_DekuTree() { }, { // Exits Entrance(RR_DEKU_TREE_BOSS_EXIT, []{return true;}), - Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->DekuTreeClear;}, false), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->Get(LOGIC_DEKU_TREE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 3a5a850ba..1bb3cb1ed 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -24,7 +24,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_LOBBY] = Region("Dodongos Cavern Lobby", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->GossipStoneFairy, []{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);), @@ -37,15 +37,15 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_BEGINNING, []{return true;}), Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, []{return logic->IsAdult;}), Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}), - Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->DCStairsRoomDoor;}), - Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->DCLiftPlatform;}), - Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->DCEyesLit;}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->Get(LOGIC_DC_STAIRS_ROOM_DOOR);}), + Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->Get(LOGIC_DC_LIFT_PLATFORM);}), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->Get(LOGIC_DC_EYES_LIT);}), Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, []{return false;}), }); areaTable[RR_DODONGOS_CAVERN_LOBBY_SWITCH] = Region("Dodongos Cavern Lobby Switch", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->DCStairsRoomDoor, []{return true;}), + EventAccess(LOGIC_DC_STAIRS_ROOM_DOOR, []{return true;}), }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, []{return true;}), @@ -85,7 +85,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->DCKilledLowerLizalfos, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);}), + EventAccess(LOGIC_DC_KILLED_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), @@ -95,8 +95,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->DCKilledLowerLizalfos;}), - Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->DCKilledLowerLizalfos;}), + Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->Get(LOGIC_DC_KILLED_LOWER_LIZALFOS);}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->Get(LOGIC_DC_KILLED_LOWER_LIZALFOS);}), }); areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Region("Dodongos Cavern Dodongo Room", SCENE_DODONGOS_CAVERN, {}, { @@ -132,7 +132,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Region("Dodongos Cavern Stairs Upper", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, logic->DCLiftPlatform ? ED_BOOMERANG : ED_LONGSHOT)), + LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, logic->Get(LOGIC_DC_LIFT_PLATFORM) ? ED_BOOMERANG : ED_LONGSHOT)), LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, logic->CanBreakPots()), @@ -208,8 +208,8 @@ void RegionTable_Init_DodongosCavern() { //Exits Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->DCKilledLowerLizalfos;}), - Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->DCKilledLowerLizalfos;}), + Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, []{return logic->Get(LOGIC_DC_KILLED_LOWER_LIZALFOS);}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->Get(LOGIC_DC_KILLED_LOWER_LIZALFOS);}), }); areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Region("Dodongos Cavern Second Slingshot Room", SCENE_DODONGOS_CAVERN, {}, { @@ -236,8 +236,8 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_FAR_BRIDGE] = Region("Dodongos Cavern Far Bridge", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->DCEyesLit, []{return logic->HasExplosives();}), - EventAccess(&logic->DCLiftPlatform, []{return true;}), + EventAccess(LOGIC_DC_EYES_LIT, []{return logic->HasExplosives();}), + EventAccess(LOGIC_DC_LIFT_PLATFORM, []{return true;}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, logic->CanBreakMudWalls()), @@ -249,7 +249,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOSS_AREA] = Region("Dodongos Cavern Boss Region", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Location LOCATION(RC_DODONGOS_CAVERN_BEFORE_BOSS_GRASS, logic->CanCutShrubs()), @@ -295,12 +295,13 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->HasItem(RG_GORONS_BRACELET) && logic->TakeDamage();});}), //strength 1 and bunny speed works too Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->IsAdult;}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->DCEyesLit;}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->Get(LOGIC_DC_EYES_LIT);}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return Here(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}), }); areaTable[RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE] = Region("Dodongos Cavern MQ Gossip Stone", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, true), @@ -313,12 +314,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->ClearMQDCUpperLobbyRocks, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), - EventAccess(&logic->DCEyesLit, []{return logic->HasExplosives() || (logic->ClearMQDCUpperLobbyRocks && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));}), + EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), + EventAccess(LOGIC_DC_EYES_LIT, []{return logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));}), }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->ClearMQDCUpperLobbyRocks;}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS);}), //Bunny hood jump + jumpslash can also make it directly from the raising platform Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && logic->CanJumpslashExceptHammer() && logic->TakeDamage());}), //RANDOTODO is this possible with equip swapped hammer? //it is possible to use bunny hood speed, hovers and a jumpslash to go between here and the other bridge (included with TORCH_ROOM_LOWER), but this would be a trick @@ -326,7 +327,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER] = Region("Dodongos Cavern MQ Stairs Lower", SCENE_DODONGOS_CAVERN, { //Events - //EventAccess(&logic->CanClimbDCStairs, []{return logic->HasExplosives || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRS_WITH_BOW) && logic->CanUse(RG_FAIRY_BOW));}), + //EventAccess(LOGIC_DC_CAN_CLIMB_STAIRS, []{return logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRS_WITH_BOW) && logic->CanUse(RG_FAIRY_BOW));}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, logic->CanBreakPots()), @@ -345,8 +346,8 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL] = Region("Dodongos Cavern MQ Stairs Past Mud Wall", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - //EventAccess(&logic->CanClimbDCStairs, []{return logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + //EventAccess(LOGIC_DC_CAN_CLIMB_STAIRS, []{return logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), @@ -375,7 +376,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->TakeDamage();}), //If some case comes up where you can directly (void?)warp here without going through Dodongo room or climbing up from below, //the commented out logic is to handle going down and reclimbing to get silver rupees. A new eventVar will need decalring to handle this. - /*(logic->CanPassEnemy(RE_BIG_SKULLTULA) || CanUse(RG_HOVER_BOOTS)) && logic->CanClimbDCStairs;*/ + /*(logic->CanPassEnemy(RE_BIG_SKULLTULA) || CanUse(RG_HOVER_BOOTS)) && logic->Get(LOGIC_DC_CAN_CLIMB_STAIRS);*/ Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return true;}),//if we add BONKO or other crate logic, logic for silver rupees goes here }); @@ -394,7 +395,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Region("Dodongos Cavern MQ Torch Puzzle Lower", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->ClearMQDCUpperLobbyRocks, []{return (((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return (((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanUse(RG_BOOMERANG)), @@ -463,7 +464,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Region("Dodongos Cavern MQ Torch Puzzle Upper", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->ClearMQDCUpperLobbyRocks, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true), @@ -471,7 +472,7 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->ClearMQDCUpperLobbyRocks;}), + Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS);}), Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, []{return true;}), Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, []{return true;}), }); @@ -552,7 +553,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Region("Dodongos Cavern MQ Back Behind Fire", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->MQDCBehindFireSwitch, []{return logic->CanDetonateBombFlowers();}), + EventAccess(LOGIC_DC_MQ_BEHIND_FIRE_SWITCH, []{return logic->CanDetonateBombFlowers();}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it @@ -565,13 +566,13 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->CanAttack();}), //There's a trick N64 rolls into the child eyes trick for using armos blow up the bomb flowers when dieing, which would be killing an armos //RANDOTODO investigate using hovers to go from the door ledge to the block directly - Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->MQDCBehindFireSwitch;}), + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->Get(LOGIC_DC_MQ_BEHIND_FIRE_SWITCH);}), }); areaTable[RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE] = Region("Dodongos Cavern MQ BossArea", SCENE_DODONGOS_CAVERN, { //Events - EventAccess(&logic->MQDCBehindFireSwitch, []{return true/*str0 || logic->CanHitSwitch() || logic->CanDetonateBombFlowers()*/;}), - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_DC_MQ_BEHIND_FIRE_SWITCH, []{return true/*str0 || logic->CanHitSwitch() || logic->CanDetonateBombFlowers()*/;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET)), @@ -601,19 +602,19 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", SCENE_DODONGOS_CAVERN_BOSS, { // Events // Blue Fire Arrows need similar accuracy as hammer trick, only put in logic when both hammer & blue fire tricks enabled - EventAccess(&logic->DodongosCavernClear, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || + EventAccess(LOGIC_DODONGOS_CAVERN_CLEAR, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_DC_HAMMER_FLOOR) ? logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->BlueFire()) : ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE));}) && logic->CanKillEnemy(RE_KING_DODONGO);}), }, { // Locations LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernClear), - LOCATION(RC_KING_DODONGO, logic->DodongosCavernClear), + LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->Get(LOGIC_DODONGOS_CAVERN_CLEAR)), + LOCATION(RC_KING_DODONGO, logic->Get(LOGIC_DODONGOS_CAVERN_CLEAR)), }, { // Exits Entrance(RR_DODONGOS_CAVERN_BOSS_EXIT, []{return true;}), - Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernClear;}, false), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->Get(LOGIC_DODONGOS_CAVERN_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index d0c4dfdb7..2ccd8e6f1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -20,14 +20,14 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->FireTimer() >= 24;}), - Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked);}), + Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked());}), Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return true;}), Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), }); areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), + EventAccess(LOGIC_FAIRY_POT, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true), @@ -38,12 +38,12 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->HitFireTemplePlatform || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->Get(LOGIC_FIRE_HIT_PLATFORM) || logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked;}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked();}), Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return Here(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}), }); @@ -67,11 +67,11 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->FireLoopSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_LOOP_SWITCH, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->FireLoopSwitch;}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); areaTable[RR_FIRE_TEMPLE_LOOP_GORON_ROOM] = Region("Fire Temple Loop Goron Room", SCENE_FIRE_TEMPLE, {}, { @@ -79,14 +79,14 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, []{return logic->FireLoopSwitch;}), - Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return logic->FireLoopSwitch;}), + Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), + Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); areaTable[RR_FIRE_TEMPLE_LOOP_EXIT] = Region("Fire Temple Loop Exit", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->FireLoopSwitch;}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Region("Fire Temple Big Lava Room", SCENE_FIRE_TEMPLE, {}, { @@ -263,7 +263,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Region("Fire Temple Fire Maze Upper", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->HitFireTemplePlatform, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_HIT_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), @@ -377,7 +377,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_LIKE_LIKE);});}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->OpenedLowestGoronCage;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", SCENE_FIRE_TEMPLE, {}, { @@ -391,7 +391,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM] = Region("Fire Temple MQ Iron Knuckle Room", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), @@ -420,11 +420,11 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Fire Temple MQ Map Room North", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->OpenedLowestGoronCage, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->OpenedLowestGoronCage;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE] = Region("Fire Temple MQ Map Room Cage", SCENE_FIRE_TEMPLE, {}, { @@ -432,8 +432,8 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->OpenedLowestGoronCage;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return logic->OpenedLowestGoronCage;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), + Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", SCENE_FIRE_TEMPLE, {}, { @@ -448,7 +448,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return true;}), //Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH, []{return logic->FireTimer() > 32 && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->HitFireTemplePlatform && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))));}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))));}), }); //This room assumes tunic logic is handled on entry. @@ -495,7 +495,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM] = Region("Fire Temple MQ Torch Firewall Room", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_HOOKSHOT);}), + EventAccess(LOGIC_FAIRY_POT, []{return logic->CanUse(RG_HOOKSHOT);}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), @@ -522,7 +522,7 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return (logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC);}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->OpenedUpperFireShortcut;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), }); areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", SCENE_FIRE_TEMPLE, {}, { @@ -580,26 +580,26 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT] = Region("Fire Temple MQ Maze Shortcut", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->OpenedUpperFireShortcut, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_OPENED_UPPER_SHORTCUT, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->OpenedUpperFireShortcut;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), }); areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE] = Region("Fire Temple MQ Maze Shortcut Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->OpenedUpperFireShortcut;), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, logic->OpenedUpperFireShortcut && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, []{return logic->OpenedUpperFireShortcut;}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return logic->OpenedUpperFireShortcut;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), }); @@ -618,7 +618,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM] = Region("Fire Temple MQ Narrow Path Room", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, logic->CanBreakPots()), @@ -659,18 +659,18 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return logic->HitFireTemplePlatform;}), + Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_FIRE_HIT_PLATFORM);}), Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, []{return logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}), //Hover boots get there via the platforms Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, []{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}), - Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, []{return logic->OpenedFireMQFireMazeDoor;}), + Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, []{return logic->Get(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR);}), }); areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS] = Region("Fire Temple MQ Fire Maze Platforms", SCENE_FIRE_TEMPLE, { //Events - EventAccess(&logic->HitFireTemplePlatform, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - EventAccess(&logic->OpenedFireMQFireMazeDoor, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}), + EventAccess(LOGIC_FIRE_HIT_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}), }, {}, { Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, []{return true;}), Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}), @@ -748,15 +748,15 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", SCENE_FIRE_TEMPLE_BOSS, { // Events - EventAccess(&logic->FireTempleClear, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), + EventAccess(LOGIC_FIRE_TEMPLE_CLEAR, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}), }, { // Locations - LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), - LOCATION(RC_VOLVAGIA, logic->FireTempleClear), + LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->Get(LOGIC_FIRE_TEMPLE_CLEAR)), + LOCATION(RC_VOLVAGIA, logic->Get(LOGIC_FIRE_TEMPLE_CLEAR)), }, { // Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTempleClear;}, false), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->Get(LOGIC_FIRE_TEMPLE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index 8f6fb879f..b3aa0abc7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -34,7 +34,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_LOBBY] = Region("Forest Temple Lobby", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_MEG, []{return logic->Get(LOGIC_FOREST_JOELLE) && logic->Get(LOGIC_FOREST_BETH) && logic->Get(LOGIC_FOREST_AMY) && logic->CanKillEnemy(RE_MEG);}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()), @@ -52,7 +52,7 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}), Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 1);}), Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, []{return false;}), - Entrance(RR_FOREST_TEMPLE_BOSS_REGION, []{return logic->ForestTempleMeg;}), + Entrance(RR_FOREST_TEMPLE_BOSS_REGION, []{return logic->Get(LOGIC_FOREST_MEG);}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), }); @@ -64,7 +64,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_LOWER_STALFOS] = Region("Forest Temple Lower Stalfos", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), @@ -77,8 +77,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER] = Region("Forest Temple NW Outdoors Lower", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT)), @@ -95,8 +95,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER] = Region("Forest Temple NW Outdoors Upper", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->HookshotOrBoomerang()), @@ -112,8 +112,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER] = Region("Forest Temple NE Outdoors Lower", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT)), @@ -128,8 +128,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER] = Region("Forest Temple NE Outdoors Upper", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS)), @@ -219,10 +219,10 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleJoelle, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_JOELLE, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->ForestTempleJoelle), + LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->Get(LOGIC_FOREST_JOELLE)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), @@ -244,10 +244,10 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BLUE_POE_ROOM] = Region("Forest Temple Blue Poe Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleBeth, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_BETH, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->ForestTempleBeth), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->Get(LOGIC_FOREST_BETH)), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_3, logic->CanBreakPots()), @@ -292,7 +292,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Region("Forest Temple Green Poe Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleAmy, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_AMY, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_GREEN_POE_POT_1, logic->CanBreakPots()), @@ -300,7 +300,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, []{return true;}), - Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, []{return logic->ForestTempleAmy;}), + Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, []{return logic->Get(LOGIC_FOREST_AMY);}), }); areaTable[RR_FOREST_TEMPLE_EAST_CORRIDOR] = Region("Forest Temple East Corridor", SCENE_FOREST_TEMPLE, {}, {}, { @@ -336,7 +336,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Region("Forest Temple MQ Central Region", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanKillEnemy(RE_MEG);}), + EventAccess(LOGIC_FOREST_MEG, []{return logic->Get(LOGIC_FOREST_JOELLE) && logic->Get(LOGIC_FOREST_BETH) && logic->Get(LOGIC_FOREST_AMY) && logic->CanKillEnemy(RE_MEG);}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, logic->CanBreakPots()), @@ -352,50 +352,50 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, []{return logic->CanHitEyeTargets();}), Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return Here(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->CanKillEnemy(RE_STALFOS);});}), //implies the other 3 poes - Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, []{return logic->ForestTempleMeg;}), + Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, []{return logic->Get(LOGIC_FOREST_MEG);}), }); areaTable[RR_FOREST_TEMPLE_MQ_WOLFOS_ROOM] = Region("Forest Temple MQ Wolfos Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), - EventAccess(&logic->ForestClearBelowBowChest, []{return logic->CanKillEnemy(RE_WOLFOS);}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), + EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_WOLFOS);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, logic->ForestClearBelowBowChest), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH)), LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->ForestClearBelowBowChest && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}), }); areaTable[RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE] = Region("Forest Temple MQ Lower Block Puzzle", SCENE_FOREST_TEMPLE, { //longshot is capable of hitting the switch, but some invisible collision makes the shot harder than you would think, so it may be trickworthy - EventAccess(&logic->MQForestBlockRoomTargets, []{return (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5));}), + EventAccess(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, []{return (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5));}), //It is barely possible to get this as child with master + hovers, but it's tight without bunny speed - EventAccess(&logic->ForestCanTwistHallway, []{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_MASTER_SWORD)))) || (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}), + EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_MASTER_SWORD)))) || (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return Here(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return logic->CanKillEnemy(RE_STALFOS);});}), - Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return logic->HasItem(RG_GORONS_BRACELET) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return logic->HasItem(RG_GORONS_BRACELET) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}), //Assumes RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE access - Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), - Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->ForestCanTwistHallway && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE] = Region("Forest Temple MQ Middle Block Puzzle", SCENE_FOREST_TEMPLE, { //longshot is capable of hitting the switch, but some invisible collision makes the shot more annoying than you would think, so it may be trickworthy - EventAccess(&logic->MQForestBlockRoomTargets, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_LONGSHOT));}), - EventAccess(&logic->ForestCanTwistHallway, []{return ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD)));}), + EventAccess(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_LONGSHOT));}), + EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD)));}), }, {}, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return true;}), - Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}), //Hammer cannot recoil from here, but can make the jump forwards with a hammer jumpslash as adult - Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->ForestCanTwistHallway && logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->CanJumpslashExceptHammer() || (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER))));}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->CanJumpslashExceptHammer() || (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER))));}), }); areaTable[RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE] = Region("Forest Temple MQ After Block Puzzle", SCENE_FOREST_TEMPLE, {}, { @@ -404,7 +404,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), - Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->ForestCanTwistHallway && logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), + Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), //!QUANTUM LOGIC! //As there is no way in default logic to reach the other possible key use without going through RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, this is logically safe for now //Breaks if there's any other way to RR_FOREST_TEMPLE_MQ_FALLING_ROOM than going through the eye targets in RR_FOREST_TEMPLE_MQ_CENTRAL_AREA @@ -426,7 +426,7 @@ void RegionTable_Init_ForestTemple() { }); areaTable[RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE] = Region("Forest Temple MQ Outdoor Ledge", SCENE_FOREST_TEMPLE, { - EventAccess(&logic->ForestCanTwistHallway, []{return logic->CanHitSwitch();}), + EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return logic->CanHitSwitch();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), @@ -458,8 +458,8 @@ void RegionTable_Init_ForestTemple() { //The well only coniders the eye target here because the eye target is a temp flag, making it unwieldy to use as an EventAccess to make it it's own room areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS] = Region("Forest Temple MQ NE Outdoors", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, logic->CanHitEyeTargets() || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)), @@ -501,10 +501,10 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_JOELLE_ROOM] = Region("Forest Temple MQ Joelle room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleJoelle, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_JOELLE, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->ForestTempleJoelle), + LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->Get(LOGIC_FOREST_JOELLE)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), @@ -514,26 +514,26 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_3_STALFOS_ROOM] = Region("Forest Temple MQ 3 Stalfos Room", SCENE_FOREST_TEMPLE, { //Events //technically happens in RR_FOREST_TEMPLE_MQ_WOLFOS_ROOM, but the way this room blocks the hole means it cannot be logical to do anything else there. - EventAccess(&logic->ForestClearBelowBowChest, []{return logic->CanKillEnemy(RE_WOLFOS);}), + EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_WOLFOS);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3);}), - Entrance(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3);}), + Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3);}), + Entrance(RR_FOREST_TEMPLE_MQ_BETH_ROOM, []{return logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3);}), }); areaTable[RR_FOREST_TEMPLE_MQ_BETH_ROOM] = Region("Forest Temple MQ Beth Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleBeth, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_BETH, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->ForestTempleBeth), + LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FOREST_BETH)), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, logic->CanBreakPots()), @@ -570,29 +570,29 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_AMY_ROOM] = Region("Forest Temple MQ Amy Room", SCENE_FOREST_TEMPLE, { //Events - EventAccess(&logic->ForestTempleAmy, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_FOREST_AMY, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->ForestTempleAmy;}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->Get(LOGIC_FOREST_AMY);}), Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, []{return true;}), }); areaTable[RR_FOREST_TEMPLE_MQ_BASEMENT] = Region("Forest Temple MQ Basement", SCENE_FOREST_TEMPLE, { //Events //Implies CanHitSwitch() - EventAccess(&logic->ForestOpenBossCorridor, []{return logic->CanHitEyeTargets();}), + EventAccess(LOGIC_FOREST_OPEN_BOSS_CORRIDOR, []{return logic->CanHitEyeTargets();}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, true), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->ForestTempleMeg;}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->Get(LOGIC_FOREST_MEG);}), Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT_POT_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->TakeDamage();}), - Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, []{return logic->ForestOpenBossCorridor;}), + Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, []{return logic->Get(LOGIC_FOREST_OPEN_BOSS_CORRIDOR);}), }); areaTable[RR_FOREST_TEMPLE_MQ_BASEMENT_POT_ROOM] = Region("Forest Temple MQ Basement Pot Room", SCENE_FOREST_TEMPLE, {}, { @@ -608,7 +608,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_BOSS_REGION] = Region("Forest Temple MQ Boss Region", SCENE_FOREST_TEMPLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, []{return logic->ForestOpenBossCorridor;}), + Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, []{return logic->Get(LOGIC_FOREST_OPEN_BOSS_CORRIDOR);}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return true;}), }); @@ -624,15 +624,15 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", SCENE_FOREST_TEMPLE_BOSS, { // Events - EventAccess(&logic->ForestTempleClear, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), + EventAccess(LOGIC_FOREST_TEMPLE_CLEAR, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}), }, { // Locations - LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), - LOCATION(RC_PHANTOM_GANON, logic->ForestTempleClear), + LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->Get(LOGIC_FOREST_TEMPLE_CLEAR)), + LOCATION(RC_PHANTOM_GANON, logic->Get(LOGIC_FOREST_TEMPLE_CLEAR)), }, { // Exits Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->ForestTempleClear;}, false), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->Get(LOGIC_FOREST_TEMPLE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index a0e1f54d1..de95e359f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -35,7 +35,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_DEKU_SCRUBS] = Region("Ganon's Castle Deku Scrubs", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), @@ -54,7 +54,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ForestTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}), + EventAccess(LOGIC_FOREST_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS)), @@ -64,7 +64,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Region("Ganon's Castle Fire Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->FireTrialClear, []{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}), + EventAccess(LOGIC_FIRE_TRIAL_CLEAR, []{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), @@ -74,9 +74,9 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->BlueFireAccess, []{return true;}), - EventAccess(&logic->FairyPot, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);}), - EventAccess(&logic->WaterTrialClear, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);}), + EventAccess(LOGIC_WATER_TRIAL_CLEAR, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), @@ -88,7 +88,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Region("Ganon's Castle Shadow Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))));}), + EventAccess(LOGIC_SHADOW_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), @@ -104,8 +104,8 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->NutPot, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), - EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), + EventAccess(LOGIC_NUT_POT, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), + EventAccess(LOGIC_SPIRIT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_BOMBCHU_5))), @@ -118,7 +118,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->LightTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), + EventAccess(LOGIC_LIGHT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), @@ -163,7 +163,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_DEKU_SCRUBS] = Region("Ganon's Castle MQ Deku Scrubs", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), @@ -206,7 +206,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_FOREST_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Forest Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ForestTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_FOREST_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, logic->CanBreakPots()), @@ -225,7 +225,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Fire Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->FireTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_FIRE_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), //There's no way back across the lava without glitches }, { //Locations @@ -235,7 +235,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM] = Region("Ganon's Castle MQ Water Trial Geyser Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->BlueFireAccess, []{return logic->CanJumpslash() || logic->HasExplosives();}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->CanJumpslash() || logic->HasExplosives();}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), @@ -255,7 +255,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Water Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->WaterTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_WATER_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, logic->CanBreakPots()), @@ -267,19 +267,19 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE] = Region("Ganon's Castle MQ Shadow Trial Starting Ledge", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_SHADOW_TRIAL_FIRST_CHEST, []{return logic->CanUse(RG_FAIRY_BOW);}), }, {}, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return true;}), - Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return (logic->ShadowTrialFirstChest && logic->CanUse(RG_HOOKSHOT)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return (logic->Get(LOGIC_SHADOW_TRIAL_FIRST_CHEST) && logic->CanUse(RG_HOOKSHOT)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM] = Region("Ganon's Castle MQ Shadow Trial Chest Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(LOGIC_SHADOW_TRIAL_FIRST_CHEST, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->ShadowTrialFirstChest), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->Get(LOGIC_SHADOW_TRIAL_FIRST_CHEST)), }, { //Exits //Hookshot here is possible but very tight, but it's basically never relevant @@ -290,7 +290,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_MOVING_PLATFORM] = Region("Ganon's Castle MQ Shadow Trial Moving Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events //A torch run from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE is possible but tight, so would be a trick - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanDetonateUprightBombFlower();}), + EventAccess(LOGIC_SHADOW_TRIAL_FIRST_CHEST, []{return logic->CanDetonateUprightBombFlower();}), }, {}, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), @@ -323,7 +323,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Shadow Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_SHADOW_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, logic->CanBreakPots()), @@ -365,8 +365,8 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Spirit Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_SPIRIT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, logic->CanBreakPots()), @@ -410,7 +410,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Light Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->LightTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(LOGIC_LIGHT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, logic->CanBreakPots()), @@ -426,12 +426,12 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_LOBBY, []{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}), Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}), //RANDOTODO could we just set these events automatically based on the setting? - Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && - (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && - (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && - (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && - (logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && - (logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}), + Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->Get(LOGIC_FOREST_TRIAL_CLEAR) || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + (logic->Get(LOGIC_FIRE_TRIAL_CLEAR) || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && + (logic->Get(LOGIC_WATER_TRIAL_CLEAR) || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && + (logic->Get(LOGIC_SHADOW_TRIAL_CLEAR) || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && + (logic->Get(LOGIC_SPIRIT_TRIAL_CLEAR) || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && + (logic->Get(LOGIC_LIGHT_TRIAL_CLEAR) || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}), }); areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", SCENE_GANONS_TOWER, {}, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 68e1184ab..c3f5b3f10 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -151,7 +151,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER] = Region("Gerudo Training Ground MQ Center", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(&logic->MQGTGMazeSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_GTG_MQ_MAZE_SWITCH, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, logic->CanBreakCrates()), @@ -178,7 +178,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM] = Region("Gerudo Training Ground MQ Stalfos Room", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(&logic->BlueFireAccess, []{return true;}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations //implies logic->CanKillEnemy(RE_BIG_SKULLTULA) @@ -205,7 +205,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM] = Region("Gerudo Training Ground MQ Magenta Fire Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->MQGTGMazeSwitch), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->Get(LOGIC_GTG_MQ_MAZE_SWITCH)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return true;}), @@ -233,14 +233,14 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE] = Region("Gerudo Training Ground MQ Switch Ledge", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(&logic->MQGTGRightSideSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - EventAccess(&logic->GTGPlatformSilverRupees, []{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}), + EventAccess(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}), }, {}, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, []{return logic->CanUse(RG_FIRE_ARROWS);}), //the fire bubble here is a jerk if you are aiming for the nearest hook platform, you have to aim to the right hand side with hook to dodge it - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return logic->CanUse(RG_LONGSHOT) || (logic->GTGPlatformSilverRupees && logic->CanUse(RG_HOOKSHOT)) || ((logic->CanUse(RG_FIRE_ARROWS) && logic->GTGPlatformSilverRupees) && logic->CanUse(RG_HOVER_BOOTS));}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->MQGTGRightSideSwitch && logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return logic->CanUse(RG_LONGSHOT) || (logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES) && logic->CanUse(RG_HOOKSHOT)) || ((logic->CanUse(RG_FIRE_ARROWS) && logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES)) && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && logic->CanUse(RG_LONGSHOT);}), }); //this region exists to place silver rupee items on later, normally it's all on fire and cannot be stood on without access from another area @@ -263,24 +263,24 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH] = Region("Gerudo Training Ground MQ Platforms Unlit Torch", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(&logic->GTGPlatformSilverRupees, []{return logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS);}), + EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS);}), }, {}, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, []{return logic->GTGPlatformSilverRupees;}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, []{return logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES);}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, []{return logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, []{return logic->HasFireSource() || logic->CanUse(RG_LONGSHOT);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->MQGTGRightSideSwitch && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->HasFireSource()));}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->HasFireSource()));}), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS] = Region("Gerudo Training Ground Torch Side Platforms", SCENE_GERUDO_TRAINING_GROUND, { //Events //this torch shot is possible as child but tight and obtuse enough to be a trick - EventAccess(&logic->GTGPlatformSilverRupees, []{return ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS);}), + EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS);}), }, {}, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, []{return ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->MQGTGRightSideSwitch && ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT));}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, []{return logic->Get(LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH) && ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT));}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, []{return true;}), }); @@ -296,7 +296,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT] = Region("Gerudo Training Ground MQ Maze Right", SCENE_GERUDO_TRAINING_GROUND, { //Events - EventAccess(&logic->GTGPlatformSilverRupees, []{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}), + EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), @@ -305,7 +305,7 @@ void RegionTable_Init_GerudoTrainingGround() { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT) || (logic->GTGPlatformSilverRupees && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT) || (logic->Get(LOGIC_GTG_PLATFORM_SILVER_RUPEES) && logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, []{return logic->CanUse(RG_FIRE_ARROWS);}), Entrance(RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, []{return logic->CanUse(RG_FIRE_ARROWS);}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 354da0f64..9aaaf27a5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -27,7 +27,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MAIN] = Region("Ice Cavern", SCENE_ICE_CAVERN, { //Events - EventAccess(&logic->BlueFireAccess, []{return logic->IsAdult;}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsAdult;}), }, { //Locations LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), @@ -71,7 +71,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_HUB] = Region("Ice Cavern MQ Hub", SCENE_ICE_CAVERN, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, logic->CanBreakPots()), @@ -93,7 +93,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_MAP_ROOM] = Region("Ice Cavern MQ Map Room", SCENE_ICE_CAVERN, { //Events //Child can fit between the stalagmites on the left hand side - EventAccess(&logic->BlueFireAccess, []{return logic->IsChild || logic->CanJumpslash() || logic->HasExplosives();}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsChild || logic->CanJumpslash() || logic->HasExplosives();}), }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return logic->CanHitSwitch();})), @@ -132,7 +132,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", SCENE_ICE_CAVERN, { //Events - EventAccess(&logic->BlueFireAccess, []{return true;}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index 51e80fc0c..c473f6764 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -25,31 +25,31 @@ void RegionTable_Init_JabuJabusBelly() { //Combines Lift room middle and lower, 1F holes room, the forked corridor, and it's side rooms areaTable[RR_JABU_JABUS_BELLY_MAIN] = Region("Jabu Jabus Belly Main", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuWestTentacle, []{return logic->JabuRutoIn1F && logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), + EventAccess(LOGIC_JABU_WEST_TENTACLE, []{return logic->Get(LOGIC_JABU_RUTO_IN_1F) && logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku()), //We can kill the Stingers with ruto - LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->JabuRutoIn1F), - LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->JabuWestTentacle), + LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->Get(LOGIC_JABU_RUTO_IN_1F)), + LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE)), LOCATION(RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, logic->CanBreakSmallCrates()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_BEGINNING, []{return true;}), Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, []{return true;}), - Entrance(RR_JABU_JABUS_BELLY_COMPASS_ROOM, []{return logic->JabuWestTentacle;}), - Entrance(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->JabuWestTentacle;}), - Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->JabuEastTentacle;}), - Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->JabuNorthTentacle;}), - Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, []{return logic->LoweredJabuPath || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_JABU_JABUS_BELLY_COMPASS_ROOM, []{return logic->Get(LOGIC_JABU_WEST_TENTACLE);}), + Entrance(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->Get(LOGIC_JABU_WEST_TENTACLE);}), + Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->Get(LOGIC_JABU_EAST_TENTACLE);}), + Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->Get(LOGIC_JABU_NORTH_TENTACLE);}), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_JABU_LOWERED_PATH) || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->CanUse(RG_HOVER_BOOTS));}), }); //contains B1 of hole room (aside from the ledge leading to big octo), 2 octorock room and north water switch room areaTable[RR_JABU_JABUS_BELLY_B1_NORTH] = Region("Jabu Jabus Belly B1 North", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuRutoIn1F, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), - EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK));}), + EventAccess(LOGIC_JABU_RUTO_IN_1F, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), + EventAccess(LOGIC_FAIRY_POT, []{return logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK));}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, logic->HookshotOrBoomerang()), @@ -70,7 +70,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE] = Region("Jabu Jabus Belly Water Switch Room Ledge", SCENE_JABU_JABU, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations //this is the logic for climbing back and forth to use the pots to kill the skull... or killing the skull before climbing to grab the token @@ -105,19 +105,19 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_BLUE_TENTACLE] = Region("Jabu Jabus Belly Blue Tentacle", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuEastTentacle, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), + EventAccess(LOGIC_JABU_EAST_TENTACLE, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), }, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->JabuEastTentacle;}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->Get(LOGIC_JABU_EAST_TENTACLE);}), }); areaTable[RR_JABU_JABUS_BELLY_GREEN_TENTACLE] = Region("Jabu Jabus Belly Green Tentacle", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuNorthTentacle, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), + EventAccess(LOGIC_JABU_NORTH_TENTACLE, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), }, {}, { //Exits //implied logic->CanKillEnemy(RE_BARI) - Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->JabuNorthTentacle;}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->Get(LOGIC_JABU_NORTH_TENTACLE);}), }); areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE] = Region("Jabu Jabus Belly Bigocto Room", SCENE_JABU_JABU, {}, { @@ -128,13 +128,13 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Exits Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, []{return true;}), - Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, []{return logic->JabuRutoIn1F && Here(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->CanKillEnemy(RE_BIG_OCTO);});}), + Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, []{return logic->Get(LOGIC_JABU_RUTO_IN_1F) && Here(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->CanKillEnemy(RE_BIG_OCTO);});}), }); areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Region("Jabu Jabus Belly Above Bigocto", SCENE_JABU_JABU, { //Events - EventAccess(&logic->FairyPot, []{return true;}), - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, logic->CanBreakPots()), @@ -147,7 +147,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_LIFT_UPPER] = Region("Jabu Jabus Belly Lift Upper", SCENE_JABU_JABU, { //Events - EventAccess(&logic->LoweredJabuPath, []{return true;}), + EventAccess(LOGIC_JABU_LOWERED_PATH, []{return true;}), }, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return true;}), @@ -168,7 +168,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_BEGINNING] = Region("Jabu Jabus Belly MQ Beginning", SCENE_JABU_JABU, { //Events - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash()), @@ -185,7 +185,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM] = Region("Jabu Jabus Belly MQ Lift Room", SCENE_JABU_JABU, { //Events - EventAccess(&logic->MQJabuLiftRoomCow, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);}), + EventAccess(LOGIC_JABU_MQ_LIFT_ROOM_COW, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), @@ -198,14 +198,14 @@ void RegionTable_Init_JabuJabusBelly() { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, []{return true;}), Entrance(RR_JABU_JABUS_BELLY_MQ_UNDERWATER_ALCOVE, []{return logic->HasItem(RG_SILVER_SCALE) || (logic->HasItem(RG_BRONZE_SCALE) && ((logic->IsChild || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE))));}), - Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->MQJabuHolesRoomDoor;}), - Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE, []{return logic->LoweredJabuPath || logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && logic->MQJabuLiftRoomCow);}), + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->Get(LOGIC_JABU_MQ_HOLES_ROOM_DOOR);}), + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE, []{return logic->Get(LOGIC_JABU_LOWERED_PATH) || logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && logic->Get(LOGIC_JABU_MQ_LIFT_ROOM_COW));}), //If opening RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM by lowering the geyser as 1 age is to let the other through is relevant, it needs an eventAccess }); areaTable[RR_JABU_JABUS_BELLY_MQ_UNDERWATER_ALCOVE] = Region("Jabu Jabus Belly MQ Underwater Alcove", SCENE_JABU_JABU, { //Events - EventAccess(&logic->MQJabuHolesRoomDoor, []{return true;}), + EventAccess(LOGIC_JABU_MQ_HOLES_ROOM_DOOR, []{return true;}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))), @@ -234,8 +234,8 @@ void RegionTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, []{return true;}), Entrance(RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, []{return true;}), Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->CanUse(RG_BOOMERANG) && logic->HasExplosives() && Here(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);});}), - Entrance(RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, []{return logic->JabuNorthTentacle;}), - Entrance(RR_JABU_JABUS_BELLY_MQ_PAST_OCTO, []{return logic->JabuWestTentacle && Here(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanKillEnemy(RE_BIG_OCTO);}) && logic->CanUse(RG_FAIRY_SLINGSHOT);}), + Entrance(RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, []{return logic->Get(LOGIC_JABU_NORTH_TENTACLE);}), + Entrance(RR_JABU_JABUS_BELLY_MQ_PAST_OCTO, []{return logic->Get(LOGIC_JABU_WEST_TENTACLE) && Here(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanKillEnemy(RE_BIG_OCTO);}) && logic->CanUse(RG_FAIRY_SLINGSHOT);}), }); areaTable[RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM] = Region("Jabu Jabus Belly MQ Water Switch Room", SCENE_JABU_JABU, {}, { @@ -257,7 +257,7 @@ void RegionTable_Init_JabuJabusBelly() { //Includes Like Like room areaTable[RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR] = Region("Jabu Jabus Belly MQ Forked Corridor", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuNorthTentacle, []{return Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->BlastOrSmash();}) && logic->CanUse(RG_BOOMERANG);}), + EventAccess(LOGIC_JABU_NORTH_TENTACLE, []{return Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->BlastOrSmash();}) && logic->CanUse(RG_BOOMERANG);}), }, { //Locations //Implies CanKillEnemy(RE_LIKE_LIKE) @@ -276,7 +276,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS] = Region("Jabu Jabus Belly MQ West Forked Rooms", SCENE_JABU_JABU, { //Events - EventAccess(&logic->JabuWestTentacle, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), + EventAccess(LOGIC_JABU_WEST_TENTACLE, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, Here(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, []{return logic->HasExplosives();}) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), @@ -302,13 +302,13 @@ void RegionTable_Init_JabuJabusBelly() { && ((logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && logic->CanUse(RG_IRON_BOOTS)))))), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return (logic->JabuNorthTentacle || logic->TakeDamage()) && logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return (logic->Get(LOGIC_JABU_NORTH_TENTACLE) || logic->TakeDamage()) && logic->HasItem(RG_BRONZE_SCALE);}), }); areaTable[RR_JABU_JABUS_BELLY_MQ_PAST_OCTO] = Region("Jabu Jabus Belly MQ Past Octo", SCENE_JABU_JABU, { //Events //if a hover up to the path is added, this will want it's own room - EventAccess(&logic->LoweredJabuPath, []{return logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_FAIRY_SLINGSHOT);}), + EventAccess(LOGIC_JABU_LOWERED_PATH, []{return logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_FAIRY_SLINGSHOT);}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_FAIRY_SLINGSHOT)), @@ -326,16 +326,16 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE] = Region("Jabu Jabus Belly MQ Lift Room East Ledge", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, logic->MQJabuLiftRoomCow), + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, logic->Get(LOGIC_JABU_MQ_LIFT_ROOM_COW)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, []{return true;}), - Entrance(RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, []{return logic->JabuNorthTentacle;}), + Entrance(RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, []{return logic->Get(LOGIC_JABU_NORTH_TENTACLE);}), }); areaTable[RR_JABU_JABUS_BELLY_MQ_EAST_ROOM] = Region("Jabu Jabus Belly MQ Boss Region", SCENE_JABU_JABU, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), @@ -365,7 +365,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", SCENE_JABU_JABU_BOSS, { // Events //todo: add pot kill trick - EventAccess(&logic->JabuJabusBellyClear, []{return logic->CanKillEnemy(RE_BARINADE);}), + EventAccess(LOGIC_JABU_JABUS_BELLY_CLEAR, []{return logic->CanKillEnemy(RE_BARINADE);}), }, { // Locations LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), @@ -374,12 +374,12 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_4, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_5, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_6, logic->CanBreakPots()), - LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyClear), - LOCATION(RC_BARINADE, logic->JabuJabusBellyClear), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->Get(LOGIC_JABU_JABUS_BELLY_CLEAR)), + LOCATION(RC_BARINADE, logic->Get(LOGIC_JABU_JABUS_BELLY_CLEAR)), }, { // Exits Entrance(RR_JABU_JABUS_BELLY_BOSS_EXIT, []{return false;}), - Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyClear;}, false), + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->Get(LOGIC_JABU_JABUS_BELLY_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index e5d2610f5..6b029899b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -18,7 +18,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, { //Events - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), @@ -39,7 +39,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", SCENE_SHADOW_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), //This fairy pot is only on 3DS + EventAccess(LOGIC_FAIRY_POT, []{return true;}), //This fairy pot is only on 3DS }, { //Locations LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), @@ -183,7 +183,7 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), - Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->ShadowShortcutBlock;}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->Get(LOGIC_SHADOW_SHORTCUT_BLOCK);}), //WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum }); @@ -260,7 +260,7 @@ void RegionTable_Init_ShadowTemple() { //while the spikes here are annoying, they don't really stop you doing anything, so I'll assume either lens trick, lens to see them, or taking damage from them. Not hovers though as a new player won't see the threat without lens to react properly areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM] = Region("Shadow Temple MQ Floor Spikes Room", SCENE_SHADOW_TEMPLE, { //Events //lens or trick is always required for hookshot targets. We handle it here to not complicate the RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_UPPER_DOOR logic - EventAccess(&logic->MQShadowFloorSpikeRupees, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + EventAccess(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && //Upper door side high rupee needs (hookshot and redead kill(as either age) for chest and adult) or longshot. hovers can cross from the left side with a backflip but that would be a trick //East midair rupee needs (hookshot and(hover boots or jumpslash from the upper door platform)) or longshot. //Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads)))) @@ -272,9 +272,9 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), + Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->Get(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES);}), //We need to assume we can get here with or without the glass platforms - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->Get(LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES) || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, { @@ -304,7 +304,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", SCENE_SHADOW_TEMPLE, { //Events - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO)), @@ -321,14 +321,14 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", SCENE_SHADOW_TEMPLE, { //Events - EventAccess(&logic->ShadowShortcutBlock, []{return logic->HasItem(RG_GORONS_BRACELET);}), + EventAccess(LOGIC_SHADOW_SHORTCUT_BLOCK, []{return logic->HasItem(RG_GORONS_BRACELET);}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->ShadowShortcutBlock;}), + Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->Get(LOGIC_SHADOW_SHORTCUT_BLOCK);}), Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5);}), //funnily enough, the wheel jump seems to be in logic as there's no strength requirement in N64 Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), @@ -409,15 +409,15 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE_BOSS, { // Events - EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), + EventAccess(LOGIC_SHADOW_TEMPLE_CLEAR, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), }, { // Locations - LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), - LOCATION(RC_BONGO_BONGO, logic->ShadowTempleClear), + LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->Get(LOGIC_SHADOW_TEMPLE_CLEAR)), + LOCATION(RC_BONGO_BONGO, logic->Get(LOGIC_SHADOW_TEMPLE_CLEAR)), }, { // Exits Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->ShadowTempleClear;}, false), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->Get(LOGIC_SHADOW_TEMPLE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 2e2edb5b8..8b75e7b95 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -29,7 +29,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_CHILD] = Region("Child Spirit Temple", SCENE_SPIRIT_TEMPLE, { //Events - EventAccess(&logic->NutCrate, []{return true;}), + EventAccess(LOGIC_NUT_CRATE, []{return true;}), }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), @@ -156,7 +156,7 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Spirit1FSilverRupees), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), @@ -171,10 +171,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_1F_WEST] = Region("Spirit Temple MQ 1F West", SCENE_SPIRIT_TEMPLE, { //Events //not technically a rusted switch, but a boulder through a wall, but is part of the same trick on N64 - EventAccess(&logic->MQSpiritCrawlBoulder, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), + EventAccess(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), @@ -182,7 +182,7 @@ void RegionTable_Init_SpiritTemple() { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), - Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->IsChild && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH] = Region("Spirit Temple MQ 1F Gibdo Room South", SCENE_SPIRIT_TEMPLE, {}, {}, { @@ -202,7 +202,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", SCENE_SPIRIT_TEMPLE, { //Events //For non-fairy pot items, you can also get them with rang without killing the stalfos - EventAccess(&logic->FairyPot, []{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), + EventAccess(LOGIC_FAIRY_POT, []{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), }, { //Locations //implies logic->CanBreakPots() @@ -218,10 +218,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Spirit Temple MQ Map Room North", SCENE_SPIRIT_TEMPLE, { //Events - EventAccess(&logic->MQSpiritMapRoomEnemies, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}), + EventAccess(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->MQSpiritMapRoomEnemies), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->Get(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES)), }, { //Exits //Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire @@ -231,7 +231,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Spirit Temple MQ Map Room South", SCENE_SPIRIT_TEMPLE, { //Events //You can lure the keese over by aggroing them with dins if you use it as close to the torch keese as possible, but it's a trick as it's not intuitive and basically never comes up - EventAccess(&logic->MQSpiritMapRoomEnemies, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}), + EventAccess(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}), }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, true), @@ -244,11 +244,11 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH] = Region("Spirit Temple MQ West 1F Rusted Switch", SCENE_SPIRIT_TEMPLE, { //Events - EventAccess(&logic->MQSpiritTimeTravelChest, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - EventAccess(&logic->MQSpiritCrawlBoulder, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), + EventAccess(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), }, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}), //This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}), }); @@ -372,23 +372,23 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F] = Region("Spirit Temple MQ Three Suns Room 2F", SCENE_SPIRIT_TEMPLE, { //Events //implies logic->CanKillEnemy(RE_WALLMASTER). If we have lights, we can kill stalfos and wallmasters with bow - EventAccess(&logic->MQSpirit3SunsEnemies, []{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}), + EventAccess(LOGIC_SPIRIT_MQ_3SUNS_ENEMIES, []{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}), }, {}, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, []{return logic->MQSpirit3SunsEnemies;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, []{return logic->Get(LOGIC_SPIRIT_MQ_3SUNS_ENEMIES);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F] = Region("Spirit Temple MQ Three Suns Room 1F", SCENE_SPIRIT_TEMPLE, {}, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpirit3SunsEnemies;}), + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->Get(LOGIC_SPIRIT_MQ_3SUNS_ENEMIES);}), Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, []{return true;}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_1F_EAST] = Region("Spirit Temple MQ 1F East", SCENE_SPIRIT_TEMPLE, { //Events //Assumes RR_SPIRIT_TEMPLE_MQ_LOBBY access - EventAccess(&logic->Spirit1FSilverRupees, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_SPIRIT_1F_SILVER_RUPEES, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), @@ -555,15 +555,15 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", SCENE_SPIRIT_TEMPLE_BOSS, { // Events - EventAccess(&logic->SpiritTempleClear, []{return logic->CanKillEnemy(RE_TWINROVA);}), + EventAccess(LOGIC_SPIRIT_TEMPLE_CLEAR, []{return logic->CanKillEnemy(RE_TWINROVA);}), }, { // Locations - LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), - LOCATION(RC_TWINROVA, logic->SpiritTempleClear), + LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->Get(LOGIC_SPIRIT_TEMPLE_CLEAR)), + LOCATION(RC_TWINROVA, logic->Get(LOGIC_SPIRIT_TEMPLE_CLEAR)), }, { // Exits Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_DESERT_COLOSSUS, []{return logic->SpiritTempleClear;}, false), + Entrance(RR_DESERT_COLOSSUS, []{return logic->Get(LOGIC_SPIRIT_TEMPLE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index c87f8bc56..aee55c972 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -19,38 +19,38 @@ void RegionTable_Init_WaterTemple() { //Water Temple logic currently assumes that the locked door leading to the upper water raising location is unlocked from the start areaTable[RR_WATER_TEMPLE_LOBBY] = Region("Water Temple Lobby", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, logic->CanBreakPots() && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, logic->CanBreakPots() && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), }, { //Exits Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_WATER_TEMPLE_EAST_LOWER, []{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}), - Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}), - Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), - Entrance(RR_WATER_TEMPLE_WEST_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, []{return logic->CanWaterTempleLowFromHigh && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}), - Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, []{return logic->CanWaterTempleMiddle;}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}), + Entrance(RR_WATER_TEMPLE_NORTH_LOWER, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), + Entrance(RR_WATER_TEMPLE_WEST_LOWER, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) && logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, []{return (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE)) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}), + Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, []{return (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, []{return logic->Get(LOGIC_WATER_MIDDLE);}), Entrance(RR_WATER_TEMPLE_HIGH_WATER, []{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}), - Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->CanWaterTempleMiddle)));}), - Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, []{return logic->CanWaterTempleHigh && logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), - Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, []{return (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->Get(LOGIC_WATER_MIDDLE))));}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, []{return logic->Get(LOGIC_WATER_HIGH) && logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return (logic->Get(LOGIC_WATER_HIGH) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_LOW_FROM_HIGH, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_TORCH_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), - LOCATION(RC_WATER_TEMPLE_TORCH_POT_2, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_TORCH_POT_1, logic->CanBreakPots() && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_TORCH_POT_2, logic->CanBreakPots() && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), }, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}), - Entrance(RR_WATER_TEMPLE_MAP_ROOM, []{return logic->CanWaterTempleHigh;}), - Entrance(RR_WATER_TEMPLE_CRACKED_WALL, []{return logic->CanWaterTempleMiddle || (logic->CanWaterTempleHigh && logic->CanWaterTempleLowFromHigh && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}), - Entrance(RR_WATER_TEMPLE_TORCH_ROOM, []{return logic->CanWaterTempleLowFromHigh && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}), + Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_WATER_TEMPLE_MAP_ROOM, []{return logic->Get(LOGIC_WATER_HIGH);}), + Entrance(RR_WATER_TEMPLE_CRACKED_WALL, []{return logic->Get(LOGIC_WATER_MIDDLE) || (logic->Get(LOGIC_WATER_HIGH) && logic->Get(LOGIC_WATER_LOW_FROM_HIGH) && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}), + Entrance(RR_WATER_TEMPLE_TORCH_ROOM, []{return logic->Get(LOGIC_WATER_LOW_FROM_HIGH) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}), }); areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Region("Water Temple Map Room", SCENE_WATER_TEMPLE, {}, { @@ -121,7 +121,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOSS_KEY_ROOM] = Region("Water Temple Boss Key Room", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, true), @@ -162,15 +162,15 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 5);}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, []{return logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, []{return logic->CanWaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, []{return logic->Get(LOGIC_WATER_MIDDLE) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}), }); areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(SCENE_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())), + LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(SCENE_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->Get(LOGIC_WATER_HIGH) && logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}), @@ -204,7 +204,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_HIGH, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}), @@ -212,9 +212,9 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Region("Water Temple Block Corridor", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, []{return logic->CanUse(RG_HOOKSHOT);}), @@ -272,7 +272,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_PRE_BOSS_ROOM] = Region("Water Temple Pre Boss Room", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { // Locations LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, logic->CanBreakPots()), @@ -313,10 +313,10 @@ void RegionTable_Init_WaterTemple() { //A special entry as we can't set it to high after entering at a lower height Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, []{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT));}), Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, []{return (logic->MQWaterLevel(WL_MID) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->HasItem(RG_BRONZE_SCALE);}), - Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, []{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || ((logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) && logic->HasItem(RG_BRONZE_SCALE)));}), - Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, []{return logic->MQWaterB1Switch && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_SILVER_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), + Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && (logic->MQWaterLevel(WL_LOW) || ((logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) && logic->HasItem(RG_BRONZE_SCALE)));}), + Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_SILVER_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), //Adult needs to jump in instead of dive for swim access, but you just hold forward. RT_WATER_BK_REGION Isn't relevant unless the Dark Link loop can be done without longshot with other tricks - Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->MQWaterB1Switch && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT))) && (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS)));}), + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT))) && (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS)));}), }); //This region specifically covers the topmost platform around central pillar @@ -349,8 +349,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_HIGH_EMBLEM] = Region("Water Temple MQ High Emblem", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->ReachedWaterHighEmblem, []{return true;}), - EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_REACHED_HIGH_EMBLEM, []{return true;}), + EventAccess(LOGIC_WATER_HIGH, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, []{return true;}), @@ -375,10 +375,10 @@ void RegionTable_Init_WaterTemple() { //Events //if we can't reach these, we can't move the water at all, so no need to specify level or account for WL_LOW access here //review is some way to play ocarina underwater exists - EventAccess(&logic->CouldWaterTempleLow, []{return true;}), - EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_COULD_LOW, []{return true;}), + EventAccess(LOGIC_WATER_LOW_FROM_HIGH, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), //Reserved for glitches/tricks that could do this - //EventAccess(&logic->CanWaterTempleLowFromMid, []{return false;}), + //EventAccess(LOGIC_WATER_LOW_FROM_MIDDLE, []{return false;}), }, { //Locations LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->MQWaterLevel(WL_HIGH) && logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)), @@ -401,48 +401,48 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F] = Region("Water Temple MQ Central Pillar 1F", SCENE_WATER_TEMPLE, { //Events //This is harder than the other possibilities as you have to move between shots on top of the extra range, but there's basically no universe this should matter. - EventAccess(&logic->MQWaterB1Switch, []{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}), + EventAccess(LOGIC_WATER_MQ_B1_SWITCH, []{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, []{return logic->MQWaterLevel(WL_HIGH) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE);}), //I don't know if this FW trick can ever matter but maybe it's needed to get child to CENTRAL_2F or something Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, []{return logic->CanUse(RG_HOOKSHOT) || (logic->MQWaterLevel(WL_MID) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE));}), //if the gate is open, you sink straight in, so you can't climb up this way in logic without swimming - Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_HIGH_OR_MID) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->Get(LOGIC_WATER_MQ_B1_OPENED_PILLAR) && logic->MQWaterLevel(WL_HIGH_OR_MID) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), }); //If we enter here in WL_HIGH, go to RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH instead, Assumes WL_MID_OR_LOW areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F] = Region("Water Temple MQ Central Pillar 2F", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->CouldWaterTempleMiddle, []{return true;}), - EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_WATER_COULD_MIDDLE, []{return true;}), + EventAccess(LOGIC_WATER_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), //It's possible to do this even on low water, but more awkward. I'm not sure if it's even possible for it to be relevant though. - EventAccess(&logic->MQWaterOpenedPillarB1, []{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}), + EventAccess(LOGIC_WATER_MQ_B1_OPENED_PILLAR, []{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}), //this could theoretically matter once OI and equip swap is in logic, as one age may be able to get here dry and not wet, and the other may not be able to OI, but as you can OI with hookshot it probably never happens - //EventAccess(&logic->MQWaterPillarSoTBlock, []{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME);}), + //EventAccess(LOGIC_WATER_MQ_PILLAR_SOT_BLOCK, []{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME);}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, []{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_FARORES_WIND) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), - Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->Get(LOGIC_WATER_MQ_B1_OPENED_PILLAR) && logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), }); areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH] = Region("Water Temple MQ Central Pillar High", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->MQWaterOpenedPillarB1, []{return ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_DINS_FIRE)) || (ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS))) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash()));}), + EventAccess(LOGIC_WATER_MQ_B1_OPENED_PILLAR, []{return ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_DINS_FIRE)) || (ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS))) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash()));}), }, { //Locations LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, logic->CanBreakCrates()), }, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}), }); //Assuming tunic and irons was checked on entry areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1] = Region("Water Temple MQ Central Pillar B1", SCENE_WATER_TEMPLE, {}, {}, { //Exits //Can't know water level, so we'll just assume any possibility and skip to MAIN - Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->MQWaterOpenedPillarB1 && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_OPENED_PILLAR) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE);}), //Child needs to release irons for height to push down the larger "peg", however they can push the lower one down by climbing and then hit the switch through the larger peg, but it's a trick Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL, []{return ((logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)));}), }); @@ -558,25 +558,25 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, []{return true;}), - Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, []{return (logic->MQWaterStalfosPit && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->MQWaterStalfosPit && logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, []{return (logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && logic->CanUse(RG_LONGSHOT);}), }); areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT] = Region("Water Temple MQ Stalfos Pit", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->MQWaterStalfosPit, []{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOMB_THROW, true, 3, false, true)));}), + EventAccess(LOGIC_WATER_MQ_STALFOS_PIT, []{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOMB_THROW, true, 3, false, true)));}), }, {}, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}), - Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, []{return (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && (logic->CanUse(RG_HOVER_BOOTS) || logic->MQWaterStalfosPit));}), - Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->MQWaterStalfosPit && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, []{return (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && (logic->CanUse(RG_HOVER_BOOTS) || logic->Get(LOGIC_WATER_MQ_STALFOS_PIT)));}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && logic->CanUse(RG_HOOKSHOT);}), }); //also includes the suns fairy in the middle areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS] = Region("Water Temple MQ Stalfos Pit Pots", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), - EventAccess(&logic->NutPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, logic->CanBreakPots()), @@ -585,9 +585,9 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->MQWaterStalfosPit && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}), + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, []{return logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}), Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, []{return true;}), - Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, []{return logic->Get(LOGIC_WATER_MQ_STALFOS_PIT) && logic->CanUse(RG_HOOKSHOT);}), }); //specifically the area past the spikes @@ -606,7 +606,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK] = Region("Water Temple MQ After Dark Link", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, logic->CanBreakPots()), @@ -628,7 +628,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_RIVER_POTS] = Region("Water Temple MQ River Pots", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations LOCATION(RC_WATER_TEMPLE_MQ_RIVER_POT_1, logic->CanBreakPots()), @@ -660,7 +660,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", SCENE_WATER_TEMPLE, { //Events - EventAccess(&logic->MQWaterDragonTorches, []{return logic->HasFireSource();}), + EventAccess(LOGIC_WATER_MQ_DRAGON_TORCHES, []{return logic->HasFireSource();}), }, { //Locations @@ -687,7 +687,7 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, []{return logic->CanUse(RG_LONGSHOT);}), Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, []{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, []{return logic->HasItem(RG_SILVER_SCALE);}), - Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->MQWaterDragonTorches;}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->Get(LOGIC_WATER_MQ_DRAGON_TORCHES);}), }); areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH] = Region("Water Temple MQ Boss Key Room Switch", SCENE_WATER_TEMPLE, {}, { @@ -729,26 +729,26 @@ void RegionTable_Init_WaterTemple() { //Events //If the water is low, the switch is underwater and needs irons to press, otherwise, the water is too low to climb up and you need irons to hookshot a target //If a glitch clips through the gate on low, have it logically press the switch and let entrance logic enter - EventAccess(&logic->MQWaterB1Switch, []{return logic->CanUse(RG_IRON_BOOTS);}), + EventAccess(LOGIC_WATER_MQ_B1_SWITCH, []{return logic->CanUse(RG_IRON_BOOTS);}), }, {}, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16));}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && (logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16));}), Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && (logic->MQWaterLevel(WL_LOW) || logic->WaterTimer() >= 24);}) }); areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), }, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->MQWaterB1Switch && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->CanUse(RG_FIRE_ARROWS) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->CanUse(RG_LONGSHOT) && Here(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, []{return logic->ScarecrowsSong();})));}) }); @@ -780,7 +780,7 @@ void RegionTable_Init_WaterTemple() { { //Exits //we can backflip over the spikes, but land in water. - Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && (logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE));}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && (logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE));}), //Child can use the crate to get the height to make it with hovers, but it's annoyingly tight so would be a trick Entrance(RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM, []{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && //We're putting the requirement to get out of the water here as the scarecrow method in includes hook which satisfies it @@ -850,15 +850,15 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", SCENE_WATER_TEMPLE_BOSS, { // Events - EventAccess(&logic->WaterTempleClear, []{return logic->CanKillEnemy(RE_MORPHA);}), + EventAccess(LOGIC_WATER_TEMPLE_CLEAR, []{return logic->CanKillEnemy(RE_MORPHA);}), }, { // Locations - LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), - LOCATION(RC_MORPHA, logic->WaterTempleClear), + LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->Get(LOGIC_WATER_TEMPLE_CLEAR)), + LOCATION(RC_MORPHA, logic->Get(LOGIC_WATER_TEMPLE_CLEAR)), }, { // Exits Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_LAKE_HYLIA, []{return logic->WaterTempleClear;}, false), + Entrance(RR_LAKE_HYLIA, []{return logic->Get(LOGIC_WATER_TEMPLE_CLEAR);}, false), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b9525386c..e326baba1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -18,9 +18,9 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}), - EventAccess(&logic->BugRock, []{return true;}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BUG_ROCK, []{return true;}), }, { //Locations LOCATION(RC_HC_MALON_EGG, true), @@ -69,9 +69,9 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_HC_STORMS_GROTTO_BEHIND_WALLS] = Region("HC Storms Grotto Behind Walls", SCENE_GROTTOS, { //Events - EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->WanderingBugs, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_WANDERING_BUGS, []{return true;}), }, { //Locations LOCATION(RC_HC_GS_STORMS_GROTTO, logic->HookshotOrBoomerang()), @@ -89,7 +89,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_GANONS_CASTLE_GROUNDS] = Region("Ganon's Castle Grounds", SCENE_OUTSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->BuiltRainbowBridge, []{return logic->CanBuildRainbowBridge();}), + EventAccess(LOGIC_BUILD_RAINBOW_BRIDGE, []{return logic->CanBuildRainbowBridge();}), }, { //Locations LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), @@ -97,7 +97,7 @@ void RegionTable_Init_CastleGrounds() { //Exits Entrance(RR_CASTLE_GROUNDS, []{return logic->AtNight;}), Entrance(RR_OGC_GREAT_FAIRY_FOUNTAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->AtNight;}), - Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->BuiltRainbowBridge;}), + Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->Get(LOGIC_BUILD_RAINBOW_BRIDGE);}), }); areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { @@ -116,7 +116,7 @@ void RegionTable_Init_CastleGrounds() { areaTable[RR_GANONS_CASTLE_LEDGE] = Region("Ganon's Castle Ledge", SCENE_OUTSIDE_GANONS_CASTLE, {}, {}, { // Exits - Entrance(RR_GANONS_CASTLE_GROUNDS, []{return logic->BuiltRainbowBridge;}), + Entrance(RR_GANONS_CASTLE_GROUNDS, []{return logic->Get(LOGIC_BUILD_RAINBOW_BRIDGE);}), Entrance(RR_GANONS_CASTLE_ENTRYWAY, []{return logic->IsAdult;}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index be1b2043a..15e80d6c2 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -14,7 +14,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_UPPER_LOCAL] = Region("DMC Upper Local", SCENE_DEATH_MOUNTAIN_CRATER, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3);}), }, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), @@ -75,7 +75,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", SCENE_DEATH_MOUNTAIN_CRATER, { //Events - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}), }, { //Locations LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index dbf218947..dc86bd97e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_DeathMountainTrail() { // clang-format off areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", SCENE_DEATH_MOUNTAIN_TRAIL, { //Events - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}), }, { //Locations LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), @@ -32,8 +32,8 @@ void RegionTable_Init_DeathMountainTrail() { areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", SCENE_DEATH_MOUNTAIN_TRAIL, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->BugRock, []{return logic->IsChild;}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BUG_ROCK, []{return logic->IsChild;}), }, { //Locations LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index f4b8b01c3..6f639d539 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -7,8 +7,8 @@ void RegionTable_Init_DesertColossus() { // clang-format off areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", SCENE_DESERT_COLOSSUS, { //Events - EventAccess(&logic->FairyPond, []{return logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->BugRock, []{return true;}), + EventAccess(LOGIC_FAIRY_POND, []{return logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BUG_ROCK, []{return true;}), }, { //Locations LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), @@ -34,7 +34,7 @@ void RegionTable_Init_DesertColossus() { //specifically the full oasis, after the fairies have spawned areaTable[RR_DESERT_COLOSSUS_OASIS] = Region("Desert Colossus Oasis", SCENE_DESERT_COLOSSUS, { //Events - EventAccess(&logic->FairyPond, []{return true;}), + EventAccess(LOGIC_FAIRY_POND, []{return true;}), }, { //Locations LOCATION(RC_COLOSSUS_OASIS_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 17e28d5eb..b37c4f08e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -9,7 +9,7 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSKIRTS] = Region("Gerudo Fortress Outskirts", SCENE_GERUDOS_FORTRESS, { //Events - EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), //needs climb + EventAccess(LOGIC_GF_GATE_OPEN, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), //needs climb }, { //Locations LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), @@ -18,7 +18,7 @@ void RegionTable_Init_GerudoFortress() { //Exits Entrance(RR_GV_FORTRESS_SIDE, []{return true;}), Entrance(RR_TH_1_TORCH_CELL, []{return true;}), - Entrance(RR_GF_OUTSIDE_GATE, []{return logic->GF_GateOpen;}), + Entrance(RR_GF_OUTSIDE_GATE, []{return logic->Get(LOGIC_GF_GATE_OPEN);}), Entrance(RR_GF_NEAR_GROTTO, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}), Entrance(RR_GF_OUTSIDE_GTG, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}), //You can talk to the guards to get yourself thrown in jail, so long as you have a hookshot to actually end up there @@ -46,10 +46,10 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSIDE_GTG] = Region("GF Outside GTG", SCENE_GERUDOS_FORTRESS, { //Events - EventAccess(&logic->GtG_GateOpen, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}), + EventAccess(LOGIC_GTG_GATE_OPEN, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}), }, {}, { //Exits - Entrance(RR_GF_TO_GTG, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}), + Entrance(RR_GF_TO_GTG, []{return logic->Get(LOGIC_GTG_GATE_OPEN) && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}), //Jail Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -233,16 +233,16 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_OUTSIDE_GATE] = Region("GF Outside Gate", SCENE_GERUDOS_FORTRESS, { //Events - EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), + EventAccess(LOGIC_GF_GATE_OPEN, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), }, {}, { //Exits - Entrance(RR_GF_OUTSKIRTS, []{return logic->GF_GateOpen;}), + Entrance(RR_GF_OUTSKIRTS, []{return logic->Get(LOGIC_GF_GATE_OPEN);}), Entrance(RR_WASTELAND_NEAR_FORTRESS, []{return true;}), }); areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", SCENE_GROTTOS, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index a9f0299ba..0e6fe7412 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_GerudoValley() { // clang-format off areaTable[RR_GERUDO_VALLEY] = Region("Gerudo Valley", SCENE_GERUDO_VALLEY, { //Events - EventAccess(&logic->BugRock, []{return logic->IsChild;}), + EventAccess(LOGIC_BUG_ROCK, []{return logic->IsChild;}), }, { //Locations LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), @@ -17,14 +17,14 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_GROTTO_LEDGE, []{return true;}), - Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->THRescuedAllCarpenters)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild;}), //can use cucco as child }); areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), }, { //Locations LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child @@ -80,7 +80,7 @@ void RegionTable_Init_GerudoValley() { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), Entrance(RR_GV_UPPER_STREAM, []{return true;}), - Entrance(RR_GERUDO_VALLEY, []{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->THRescuedAllCarpenters;}), + Entrance(RR_GERUDO_VALLEY, []{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS);}), Entrance(RR_GV_CARPENTER_TENT, []{return logic->IsAdult;}), Entrance(RR_GV_STORMS_GROTTO, []{return logic->IsAdult && logic->CanOpenStormsGrotto();}), Entrance(RR_GV_CRATE_LEDGE, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 9d155c3a0..2e4fa2fbe 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -7,23 +7,23 @@ void RegionTable_Init_GoronCity() { // clang-format off areaTable[RR_GORON_CITY] = Region("Goron City", SCENE_GORON_CITY, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(&logic->StickPot, []{return logic->IsChild;}), - EventAccess(&logic->BugRock, []{return logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS);}), - EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_DINS_FIRE);}), - EventAccess(&logic->GCWoodsWarpOpen, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER) || logic->GoronCityChildFire;}), - EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_STICK_POT, []{return logic->IsChild;}), + EventAccess(LOGIC_BUG_ROCK, []{return logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS);}), + EventAccess(LOGIC_GORON_CITY_CHILD_FIRE, []{return logic->IsChild && logic->CanUse(RG_DINS_FIRE);}), + EventAccess(LOGIC_GORON_CITY_WOODS_WARP_OPEN, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER) || logic->Get(LOGIC_GORON_CITY_CHILD_FIRE);}), + EventAccess(LOGIC_GORON_CITY_DARUNIAS_DOOR_OPEN_CHILD, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}), // bottle animation causes similar complications as stopping goron with Din's Fire, only put in logic when both din's & blue fire tricks enabled - EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || + EventAccess(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), }, { //Locations LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), + LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->Get(LOGIC_GORON_CITY_CHILD_FIRE) && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), - LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), + LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET))), @@ -41,9 +41,9 @@ void RegionTable_Init_GoronCity() { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), Entrance(RR_GC_MEDIGORON, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}), - Entrance(RR_GC_WOODS_WARP, []{return logic->GCWoodsWarpOpen;}), - Entrance(RR_GC_SHOP, []{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}), - Entrance(RR_GC_DARUNIAS_CHAMBER, []{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}), + Entrance(RR_GC_WOODS_WARP, []{return logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN);}), + Entrance(RR_GC_SHOP, []{return (logic->IsAdult && logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->Get(LOGIC_GORON_CITY_CHILD_FIRE) || logic->CanUse(RG_FAIRY_BOW)));}), + Entrance(RR_GC_DARUNIAS_CHAMBER, []{return (logic->IsAdult && logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)) || (logic->IsChild && logic->Get(LOGIC_GORON_CITY_DARUNIAS_DOOR_OPEN_CHILD));}), Entrance(RR_GC_GROTTO_PLATFORM, []{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}), }); @@ -60,16 +60,16 @@ void RegionTable_Init_GoronCity() { areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", SCENE_GORON_CITY, { //Events - EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), + EventAccess(LOGIC_GORON_CITY_WOODS_WARP_OPEN, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), }, {}, { //Exits - Entrance(RR_GORON_CITY, []{return logic->GCWoodsWarpOpen;}), + Entrance(RR_GORON_CITY, []{return logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN);}), Entrance(RR_THE_LOST_WOODS, []{return true;}), }); areaTable[RR_GC_DARUNIAS_CHAMBER] = Region("GC Darunias Chamber", SCENE_GORON_CITY, { //Events - EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_GORON_CITY_CHILD_FIRE, []{return logic->IsChild && logic->CanUse(RG_STICKS);}), }, { //Locations LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 2fce0854f..58e6aedae 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -7,10 +7,10 @@ void RegionTable_Init_Graveyard() { // clang-format off areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", SCENE_GRAVEYARD, { //Events - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->BugRock, []{return true;}), - EventAccess(&logic->BorrowBunnyHood, []{return logic->IsChild && logic->AtDay && logic->BorrowSpookyMask && logic->HasItem(RG_CHILD_WALLET);}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BUG_ROCK, []{return true;}), + EventAccess(LOGIC_BORROW_BUNNY_HOOD, []{return logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), @@ -88,8 +88,8 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", SCENE_WINDMILL_AND_DAMPES_GRAVE, { //Events - EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), + EventAccess(LOGIC_NUT_POT, []{return true;}), + EventAccess(LOGIC_DAMPES_WINDMILL_ACCESS, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), }, { //Locations LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), @@ -124,7 +124,7 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Region("Graveyard Warp Pad Region", SCENE_GRAVEYARD, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), }, { //Locations LOCATION(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 930ffcb4f..99d200efd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -17,9 +17,9 @@ void RegionTable_Init_HauntedWasteland() { areaTable[RR_HAUNTED_WASTELAND] = Region("Haunted Wasteland", SCENE_HAUNTED_WASTELAND, { //Events - EventAccess(&logic->FairyPot, []{return true;}), - EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->CarpetMerchant, []{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + EventAccess(LOGIC_FAIRY_POT, []{return true;}), + EventAccess(LOGIC_NUT_POT, []{return true;}), + EventAccess(LOGIC_CARPET_MERCHANT, []{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }, { //Locations LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 3d850be58..bad6215a8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -7,8 +7,8 @@ void RegionTable_Init_HyruleField() { // clang-format off areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", SCENE_HYRULE_FIELD, { //Events - EventAccess(&logic->BigPoeKill, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_EPONA) || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}), - EventAccess(&logic->BorrowRightMasks, []{return logic->IsChild && logic->BorrowBunnyHood && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET);}), + EventAccess(LOGIC_BIG_POE_KILL, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_EPONA) || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}), + EventAccess(LOGIC_BORROW_RIGHT_MASKS, []{return logic->IsChild && logic->Get(LOGIC_BORROW_BUNNY_HOOD) && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), @@ -135,8 +135,8 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_COW_GROTTO_BEHIND_WEBS] = Region("HF Cow Grotto Behind Webs", SCENE_GROTTOS, { //Events - EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BUG_SHRUB, []{return logic->CanCutShrubs();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), }, { //Locations LOCATION(RC_HF_GS_COW_GROTTO, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), @@ -173,7 +173,7 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", SCENE_GROTTOS, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 92bc9aa37..1373129e7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -7,17 +7,17 @@ void RegionTable_Init_Kakariko() { // clang-format off areaTable[RR_KAKARIKO_VILLAGE] = Region("Kakariko Village", SCENE_KAKARIKO_VILLAGE, { //Events - EventAccess(&logic->BugRock, []{return true;}), + EventAccess(LOGIC_BUG_ROCK, []{return true;}), //Open Gate setting is applied in RR_ROOT - EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}), + EventAccess(LOGIC_KAKARIKO_GATE_OPEN, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}), //Needs wallet to be able to get another mask after selling Keaton - EventAccess(&logic->BorrowSkullMask, []{return logic->IsChild && logic->CanBorrowMasks && logic->HasItem(RG_CHILD_WALLET);}), + EventAccess(LOGIC_BORROW_SKULL_MASK, []{return logic->IsChild && logic->Get(LOGIC_CAN_BORROW_MASKS) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), - LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), + LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->Get(LOGIC_WAKE_UP_ADULT_TALON))), //Can kill lower kak skulls with pots LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), @@ -68,7 +68,7 @@ void RegionTable_Init_Kakariko() { Entrance(RR_KAK_WINDMILL, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}), Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_BAZAAR_KEY);}), Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}), - Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_BOTTOM_OF_THE_WELL_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}), + Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->Get(LOGIC_DRAIN_WELL) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_BOTTOM_OF_THE_WELL_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}), Entrance(RR_KAK_POTION_SHOP_FRONT, []{return (logic->AtDay || logic->IsChild) && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}), Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}), Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}), @@ -76,7 +76,7 @@ void RegionTable_Init_Kakariko() { Entrance(RR_KAK_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult);}), Entrance(RR_KAK_IMPAS_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_THE_GRAVEYARD, []{return true;}), - Entrance(RR_KAK_BEHIND_GATE, []{return logic->IsAdult || logic->KakarikoVillageGateOpen;}), + Entrance(RR_KAK_BEHIND_GATE, []{return logic->IsAdult || logic->Get(LOGIC_KAKARIKO_GATE_OPEN);}), //adult can jump from the fence near the windmill to ledgegrab the fence near granny's shop. is in logic on N64 Entrance(RR_KAK_BACKYARD, []{return logic->IsAdult || logic->AtDay;}), }); @@ -130,7 +130,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", SCENE_KAKARIKO_CENTER_GUEST_HOUSE, { //Events - EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}), + EventAccess(LOGIC_WAKE_UP_ADULT_TALON, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}), }, {}, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -168,10 +168,10 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_WINDMILL] = Region("Kak Windmill", SCENE_WINDMILL_AND_DAMPES_GRAVE, { //Events - EventAccess(&logic->DrainWell, []{return logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_DRAIN_WELL, []{return logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS);}), }, { //Locations - LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), + LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->Get(LOGIC_DAMPES_WINDMILL_ACCESS) || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits @@ -263,14 +263,14 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_BEHIND_GATE] = Region("Kak Behind Gate", SCENE_KAKARIKO_VILLAGE, {}, {}, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->KakarikoVillageGateOpen;}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->Get(LOGIC_KAKARIKO_GATE_OPEN);}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), }); areaTable[RR_KAK_WELL] = Region("Kak Well", SCENE_KAKARIKO_VILLAGE, {}, {}, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->DrainWell;}), - Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild || (logic->DrainWell && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}), + Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->Get(LOGIC_DRAIN_WELL);}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild || (logic->Get(LOGIC_DRAIN_WELL) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 5d8ef11ec..09e5a6d4a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -7,9 +7,9 @@ void RegionTable_Init_KokiriForest() { // clang-format off areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", SCENE_KOKIRI_FOREST, { //Events - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), }, { //Locations LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), @@ -83,17 +83,17 @@ void RegionTable_Init_KokiriForest() { Entrance(RR_KF_HOUSE_OF_TWINS, []{return true;}), Entrance(RR_KF_KNOW_IT_ALL_HOUSE, []{return true;}), Entrance(RR_KF_KOKIRI_SHOP, []{return true;}), - Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_FOREST_TEMPLE_CLEAR))) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD);}), Entrance(RR_THE_LOST_WOODS, []{return true;}), - Entrance(RR_LW_BRIDGE_FROM_FOREST, []{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->DekuTreeClear;}), + Entrance(RR_LW_BRIDGE_FROM_FOREST, []{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->Get(LOGIC_DEKU_TREE_CLEAR);}), Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Region("KF Outside Deku Tree", SCENE_KOKIRI_FOREST, { //Events - EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}), - EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}), - EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), + EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), + EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), }, { //Locations LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), @@ -104,13 +104,13 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_DEKU_TREE_ENTRYWAY, []{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield));}), - Entrance(RR_KOKIRI_FOREST, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), + Entrance(RR_DEKU_TREE_ENTRYWAY, []{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD)));}), + Entrance(RR_KOKIRI_FOREST, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_DEKU_TREE_CLEAR))) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD);}), }); areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", SCENE_LINKS_HOUSE, {}, { //Locations - LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->LinksCow), + LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->Get(LOGIC_LINKS_COW)), LOCATION(RC_KF_LINKS_HOUSE_POT, logic->CanBreakPots()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 964b781ce..f88a2cb6a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -7,16 +7,16 @@ void RegionTable_Init_LakeHylia() { // clang-format off areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", SCENE_LAKE_HYLIA, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}), - EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}), - EventAccess(&logic->ChildScarecrow, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}), - EventAccess(&logic->AdultScarecrow, []{return logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BUG_SHRUB, []{return logic->IsChild && logic->CanCutShrubs();}), + EventAccess(LOGIC_CHILD_SCARECROW, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}), + EventAccess(LOGIC_ADULT_SCARECROW, []{return logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}), }, { //Locations LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), - LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), @@ -35,7 +35,7 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->WaterTempleClear)) || logic->CanUse(RG_DISTANT_SCARECROW))), + LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR))) || logic->CanUse(RG_DISTANT_SCARECROW))), LOCATION(RC_LH_LAB_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), @@ -86,7 +86,7 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_HYRULE_FIELD, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), - Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), + Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), Entrance(RR_LH_GROTTO, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index c29a5924e..df143c2da 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -7,8 +7,8 @@ void RegionTable_Init_LonLonRanch() { // clang-format off areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", SCENE_LON_LON_RANCH, { //Events - EventAccess(&logic->FreedEpona, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), - EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(LOGIC_FREED_EPONA, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(LOGIC_LINKS_COW, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), }, { //Locations LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 6c6bdb536..dc6d84875 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -12,10 +12,10 @@ void RegionTable_Init_LostWoods() { areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}), - EventAccess(&logic->BorrowSpookyMask, []{return logic->IsChild && logic->BorrowSkullMask && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BUG_SHRUB, []{return logic->IsChild && logic->CanCutShrubs();}), + EventAccess(LOGIC_BORROW_SPOOKY_MASK, []{return logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), @@ -65,7 +65,7 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", SCENE_LOST_WOODS, { //Events - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), }, { //Locations LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), @@ -111,8 +111,8 @@ void RegionTable_Init_LostWoods() { areaTable[RR_DEKU_THEATER] = Region("Deku Theater", SCENE_GROTTOS, {}, { //Locations - LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->BorrowSkullMask), - LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->BorrowRightMasks), + LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK)), + LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->Get(LOGIC_BORROW_RIGHT_MASKS)), }, { //Exits Entrance(RR_LW_BEYOND_MIDO, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 2dc140284..b82a051f0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -51,10 +51,10 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", SCENE_MARKET_GUARD_HOUSE, { //Events - EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), + EventAccess(LOGIC_CAN_EMPTY_BIG_POES, []{return logic->IsAdult;}), }, { //Locations - LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->Get(LOGIC_BIG_POE_KILL) || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), @@ -141,11 +141,11 @@ void RegionTable_Init_Market() { //Currently, mask swap in menu doesn't need access to the mask shop //If it is forced on/a setting, a copy of these events should be added to root //it also doesn't need you to open kak gate, but that might be best treated as a bug - EventAccess(&logic->CanBorrowMasks, []{return logic->HasItem(RG_ZELDAS_LETTER) && logic->KakarikoVillageGateOpen;}), - EventAccess(&logic->BorrowSkullMask, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}), - EventAccess(&logic->BorrowSpookyMask, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}), - EventAccess(&logic->BorrowBunnyHood, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}), - EventAccess(&logic->BorrowRightMasks, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}), + EventAccess(LOGIC_CAN_BORROW_MASKS, []{return logic->HasItem(RG_ZELDAS_LETTER) && logic->Get(LOGIC_KAKARIKO_GATE_OPEN);}), + EventAccess(LOGIC_BORROW_SKULL_MASK, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->Get(LOGIC_CAN_BORROW_MASKS);}), + EventAccess(LOGIC_BORROW_SPOOKY_MASK, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->Get(LOGIC_CAN_BORROW_MASKS);}), + EventAccess(LOGIC_BORROW_BUNNY_HOOD, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->Get(LOGIC_CAN_BORROW_MASKS);}), + EventAccess(LOGIC_BORROW_RIGHT_MASKS, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->Get(LOGIC_CAN_BORROW_MASKS);}), }, { //Locations LOCATION(RC_MASK_SHOP_HINT, true), @@ -164,11 +164,11 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", SCENE_BOMBCHU_BOWLING_ALLEY, { //Events - EventAccess(&logic->CouldPlayBowling, []{return (logic->HasItem(RG_CHILD_WALLET));}), + EventAccess(LOGIC_COULD_PLAY_BOWLING, []{return logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations - LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), - LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), + LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->Get(LOGIC_COULD_PLAY_BOWLING) && logic->BombchusEnabled()), + LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->Get(LOGIC_COULD_PLAY_BOWLING) && logic->BombchusEnabled()), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 9d641ac98..34425e229 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -14,7 +14,7 @@ void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", SCENE_SACRED_FOREST_MEADOW, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), }, { //Locations LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), @@ -39,7 +39,7 @@ void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", SCENE_GROTTOS, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp index 07efc4326..c3e214482 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/temple_of_time.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_TempleOfTime() { // clang-format off areaTable[RR_TOT_ENTRANCE] = Region("ToT Entrance", SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), }, { //Locations LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)), @@ -40,10 +40,7 @@ void RegionTable_Init_TempleOfTime() { Entrance(RR_TOT_BEYOND_DOOR_OF_TIME, []{return ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN) || (logic->CanUse(RG_SONG_OF_TIME) && (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY) || (logic->StoneCount() == 3 && logic->HasItem(RG_OCARINA_OF_TIME))));}), }); - areaTable[RR_TOT_BEYOND_DOOR_OF_TIME] = Region("Beyond Door of Time", SCENE_TEMPLE_OF_TIME, { - //Events - //EventAccess(&logic->TimeTravel, []{return true;}), - }, { + areaTable[RR_TOT_BEYOND_DOOR_OF_TIME] = Region("Beyond Door of Time", SCENE_TEMPLE_OF_TIME, {}, { //Locations LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp index d195c71fd..49a46bc9a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp @@ -8,8 +8,8 @@ using namespace Rando; void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_1_TORCH_CELL] = Region("Thieves Hideout 1 Torch Cell", SCENE_THIEVES_HIDEOUT, { //Events - EventAccess(&logic->THCouldFree1TorchCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), + EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER);}), }, { //Locations LOCATION(RC_TH_1_TORCH_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), @@ -17,7 +17,7 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_1_TORCH_CELL_MID_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_LEFT_POT, logic->CanBreakPots()), LOCATION(RC_TH_1_TORCH_CELL_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -26,8 +26,8 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_DOUBLE_CELL] = Region("Thieves Hideout Double Cell", SCENE_THIEVES_HIDEOUT, { //Events - EventAccess(&logic->THCouldFreeDoubleCellCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), + EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER);}), }, { //Locations LOCATION(RC_TH_DOUBLE_CELL_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), @@ -40,7 +40,7 @@ void RegionTable_Init_ThievesHideout() { LOCATION(RC_TH_LEFTMOST_JAILED_POT, logic->CanBreakPots()), LOCATION(RC_TH_DOUBLE_CELL_LEFT_CRATE, logic->CanBreakCrates()), LOCATION(RC_TH_DOUBLE_CELL_RIGHT_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), @@ -49,13 +49,13 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_DEAD_END_CELL] = Region("Thieves Hideout Dead End Cell", SCENE_THIEVES_HIDEOUT, { //Events - EventAccess(&logic->TH_CouldFreeDeadEndCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), + EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER);}), }, { //Locations LOCATION(RC_TH_DEAD_END_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), LOCATION(RC_TH_DEAD_END_CELL_CRATE, logic->CanBreakCrates()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits Entrance(RR_GF_BELOW_GS, []{return true;}), @@ -63,14 +63,14 @@ void RegionTable_Init_ThievesHideout() { areaTable[RR_TH_STEEP_SLOPE_CELL] = Region("Thieves Hideout Steep Slope Cell", SCENE_THIEVES_HIDEOUT, { //Events - EventAccess(&logic->THCouldRescueSlopeCarpenter, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), - EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && logic->SmallKeys(SCENE_THIEVES_HIDEOUT, 4) && logic->THCouldFree1TorchCarpenter && logic->THCouldFreeDoubleCellCarpenter && logic->TH_CouldFreeDeadEndCarpenter && logic->THCouldRescueSlopeCarpenter;}), + EventAccess(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER, []{return logic->CanKillEnemy(RE_GERUDO_WARRIOR);}), + EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return logic->SmallKeys(SCENE_THIEVES_HIDEOUT, ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) ? 4 : 1) && logic->Get(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER) && logic->Get(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER);}), }, { //Locations LOCATION(RC_TH_STEEP_SLOPE_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), LOCATION(RC_TH_STEEP_SLOPE_RIGHT_POT, logic->CanBreakPots()), LOCATION(RC_TH_STEEP_SLOPE_LEFT_POT, logic->CanBreakPots()), - LOCATION(RC_TH_FREED_CARPENTERS, logic->THRescuedAllCarpenters), + LOCATION(RC_TH_FREED_CARPENTERS, logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS)), }, { //Exits Entrance(RR_GF_ABOVE_GTG, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 3a626a2f9..5202e7fff 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -7,18 +7,18 @@ void RegionTable_Init_ZorasDomain() { // clang-format off areaTable[RR_ZORAS_DOMAIN] = Region("Zoras Domain", SCENE_ZORAS_DOMAIN, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(&logic->NutPot, []{return true;}), - EventAccess(&logic->StickPot, []{return logic->IsChild;}), - EventAccess(&logic->FishGroup, []{return logic->IsChild;}), - EventAccess(&logic->KingZoraThawed, []{return logic->IsAdult && logic->BlueFire();}), - EventAccess(&logic->DeliverLetter, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_NUT_POT, []{return true;}), + EventAccess(LOGIC_STICK_POT, []{return logic->IsChild;}), + EventAccess(LOGIC_FISH_GROUP, []{return logic->IsChild;}), + EventAccess(LOGIC_KING_ZORA_THAWED, []{return logic->IsAdult && logic->BlueFire();}), + EventAccess(LOGIC_DELIVER_RUTOS_LETTER, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}), }, { //Locations LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), - LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->KingZoraThawed), - LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), + LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED)), + LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED) && logic->CanUse(RG_PRESCRIPTION)), LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle()), @@ -39,7 +39,7 @@ void RegionTable_Init_ZorasDomain() { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), - Entrance(RR_ZD_BEHIND_KING_ZORA, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}), + Entrance(RR_ZD_BEHIND_KING_ZORA, []{return logic->Get(LOGIC_DELIVER_RUTOS_LETTER) || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}), Entrance(RR_ZD_SHOP, []{return logic->IsChild || logic->BlueFire();}), Entrance(RR_ZORAS_DOMAIN_ISLAND, []{return true;}), }); @@ -52,13 +52,13 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", SCENE_ZORAS_DOMAIN, { //Events - EventAccess(&logic->KingZoraThawed, []{return logic->IsAdult && logic->BlueFire();}), + EventAccess(LOGIC_KING_ZORA_THAWED, []{return logic->IsAdult && logic->BlueFire();}), }, { //Locations LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->IsChild && logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(RR_ZORAS_DOMAIN, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}), + Entrance(RR_ZORAS_DOMAIN, []{return logic->Get(LOGIC_DELIVER_RUTOS_LETTER) || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}), Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), }); @@ -79,7 +79,7 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", SCENE_GROTTOS, { //Events - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index e1062caf9..178b5ecf9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -7,8 +7,8 @@ void RegionTable_Init_ZorasFountain() { // clang-format off areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", SCENE_ZORAS_FOUNTAIN, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), }, { //Locations LOCATION(RC_ZF_GS_TREE, logic->IsChild), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index f461a1dc1..be1d245aa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -28,10 +28,10 @@ void RegionTable_Init_ZoraRiver() { areaTable[RR_ZORAS_RIVER] = Region("Zora River", SCENE_ZORAS_RIVER, { //Events - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), - EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}), - EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BUG_SHRUB, []{return logic->CanCutShrubs();}), }, { //Locations LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->IsChild), @@ -103,7 +103,7 @@ void RegionTable_Init_ZoraRiver() { areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", SCENE_GROTTOS, { //Event - EventAccess(&logic->FreeFairies, []{return true;}), + EventAccess(LOGIC_FREE_FAIRIES, []{return true;}), }, { //Locations LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_1, true), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 34ad7eac5..df0e0a928 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -56,7 +56,8 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_BOMBCHU_5: case RG_BOMBCHU_10: case RG_BOMBCHU_20: - return (BombchusEnabled() && (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant)) || + return (BombchusEnabled() && + (Get(LOGIC_BUY_BOMBCHUS) || Get(LOGIC_COULD_PLAY_BOWLING) || Get(LOGIC_CARPET_MERCHANT))) || CheckInventory(ITEM_BOMBCHU, true); case RG_FAIRY_SLINGSHOT: return CheckInventory(ITEM_SLINGSHOT, true); @@ -173,7 +174,7 @@ bool Logic::HasItem(RandomizerGet itemName) { return CheckRandoInf(RandoGetToRandInf.at(itemName)); // Boss Keys case RG_EPONA: - return FreedEpona; + return Get(LOGIC_FREED_EPONA); case RG_FOREST_TEMPLE_BOSS_KEY: case RG_FIRE_TEMPLE_BOSS_KEY: case RG_WATER_TEMPLE_BOSS_KEY: @@ -263,7 +264,7 @@ bool Logic::CanUse(RandomizerGet itemName) { switch (itemName) { // Magic items case RG_MAGIC_SINGLE: - return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); + return true; // AmmoCanDrop || (HasBottle() && Get(LOGIC_BUY_MAGIC_POTION)) case RG_DINS_FIRE: case RG_FARORES_WIND: case RG_NAYRUS_LOVE: @@ -277,7 +278,7 @@ bool Logic::CanUse(RandomizerGet itemName) { // Adult items // TODO: Uncomment those if we ever implement more item usability settings case RG_FAIRY_BOW: - return IsAdult && (AmmoCanDrop || GetInLogic(LOGIC_BUY_ARROW)); // || BowAsChild; + return IsAdult; // || BowAsChild && (AmmoCanDrop || Get(LOGIC_BUY_ARROW)); case RG_MEGATON_HAMMER: return IsAdult; // || HammerAsChild; case RG_IRON_BOOTS: @@ -316,20 +317,21 @@ bool Logic::CanUse(RandomizerGet itemName) { // Child items case RG_FAIRY_SLINGSHOT: - return IsChild && (AmmoCanDrop || GetInLogic(LOGIC_BUY_SEED)); // || SlingshotAsAdult; + return IsChild; // || SlingshotAsAdult && (AmmoCanDrop || Get(LOGIC_LOGIC_BUY_SEED)); case RG_BOOMERANG: return IsChild; // || BoomerangAsAdult; case RG_KOKIRI_SWORD: return IsChild; // || KokiriSwordAsAdult; case RG_NUTS: - return ((NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop) || GetInLogic(LOGIC_BUY_NUTS); + return Get(LOGIC_NUT_POT) || Get(LOGIC_NUT_CRATE) || Get(LOGIC_DEKU_BABA_NUTS) || Get(LOGIC_BUY_NUTS); case RG_STICKS: - return IsChild /* || StickAsAdult;*/ && (StickPot || DekuBabaSticks || GetInLogic(LOGIC_BUY_STICKS)); + return IsChild /* || StickAsAdult;*/ && + (Get(LOGIC_STICK_POT) || Get(LOGIC_DEKU_BABA_STICKS) || Get(LOGIC_BUY_STICKS)); case RG_DEKU_SHIELD: return IsChild; // || DekuShieldAsAdult; case RG_PROGRESSIVE_BOMB_BAG: case RG_BOMB_BAG: - return AmmoCanDrop || GetInLogic(LOGIC_BUY_BOMB); + return true; // AmmoCanDrop || Get(LOGIC_BUY_BOMB) case RG_PROGRESSIVE_BOMBCHUS: case RG_BOMBCHU_5: case RG_BOMBCHU_10: @@ -377,15 +379,16 @@ bool Logic::CanUse(RandomizerGet itemName) { // Bottle Items case RG_BOTTLE_WITH_BUGS: - return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS); + return Get(LOGIC_BUG_SHRUB) || Get(LOGIC_WANDERING_BUGS) || Get(LOGIC_BUG_ROCK) || Get(LOGIC_BUGS_ACCESS); case RG_BOTTLE_WITH_FISH: - return LoneFish || FishGroup || - GetInLogic(LOGIC_FISH_ACCESS); // is there any need to care about lone vs group? - case RG_BOTTLE_WITH_BLUE_FIRE: // RANDOTODO should probably be better named - return BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS); + return Get(LOGIC_LONE_FISH) || Get(LOGIC_FISH_GROUP) || + Get(LOGIC_FISH_ACCESS); // is there any need to care about lone vs group? + case RG_BOTTLE_WITH_BLUE_FIRE: // RANDOTODO should probably be better named + return Get(LOGIC_BLUE_FIRE_ACCESS); case RG_BOTTLE_WITH_FAIRY: - return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || - GetInLogic(LOGIC_FAIRY_ACCESS); + return Get(LOGIC_FAIRY_POT) || Get(LOGIC_GOSSIP_STONE_FAIRY) || Get(LOGIC_BEAN_PLANT_FAIRY) || + Get(LOGIC_BUTTERFLY_FAIRY) || Get(LOGIC_FREE_FAIRIES) || Get(LOGIC_FAIRY_POND) || + Get(LOGIC_FAIRY_ACCESS); default: SPDLOG_ERROR("CanUse reached `default` for {}. Assuming intention is no extra requirements for use so " @@ -996,17 +999,17 @@ bool Logic::MQWaterLevel(RandoWaterLevel level) { // WL_LOW in logic. Alternativly a way to reach WL_LOW from WL_MID could exist, but all glitchless methods need // you to do a Low-locked action case WL_LOW: - return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || - (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + return (Get(LOGIC_WATER_HIGH) && Get(LOGIC_WATER_LOW_FROM_HIGH)) || + (Get(LOGIC_WATER_LOW_FROM_MID) && Get(LOGIC_WATER_LOW_FROM_HIGH)); case WL_LOW_OR_MID: - return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || - (CanWaterTempleLowFromHigh && CanWaterTempleMiddle) || - (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + return (Get(LOGIC_WATER_HIGH) && Get(LOGIC_WATER_LOW_FROM_HIGH)) || + (Get(LOGIC_WATER_LOW_FROM_HIGH) && Get(LOGIC_WATER_MIDDLE)) || + (Get(LOGIC_WATER_LOW_FROM_MID) && Get(LOGIC_WATER_LOW_FROM_HIGH)); // If we can set it to High out of logic we can just repeat what we did to lower the water in the first place as // High is the default. Because of this you only need to be able to use the Low and Mid Emblems, WL_LOW could be // skipped if it was ever possible to play ZL underwater. case WL_MID: - return CanWaterTempleLowFromHigh && CanWaterTempleMiddle; + return Get(LOGIC_WATER_LOW_FROM_HIGH) && Get(LOGIC_WATER_MIDDLE); // Despite being the initial state of water temple, WL_HIGH has the extra requirement of making sure that, if we // were to lower the water out of logic, we could put it back to WL_HIGH However because it is the default // state, we do not need to check if we can actually change the water level, only to make sure we can return to @@ -1016,9 +1019,9 @@ bool Logic::MQWaterLevel(RandoWaterLevel level) { // but we assume the water is WL_MID (as if we can set it to WL_LOW, we can set it to WL_MID, as Mid Emblem has // no requirements) The latter check can be assumed for now but will want a revisit once OI tricks are added. case WL_HIGH: - return ReachedWaterHighEmblem; + return Get(LOGIC_WATER_REACHED_HIGH_EMBLEM); case WL_HIGH_OR_MID: - return ReachedWaterHighEmblem || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle); + return Get(LOGIC_WATER_REACHED_HIGH_EMBLEM) || (Get(LOGIC_WATER_LOW_FROM_HIGH) && Get(LOGIC_WATER_MIDDLE)); } SPDLOG_ERROR("MQWaterLevel reached `return false;`. Missing case for a Water Level"); assert(false); @@ -1034,12 +1037,12 @@ uint8_t Logic::BottleCount() { uint8_t item = GetSaveContext()->inventory.items[i]; switch (item) { case ITEM_LETTER_RUTO: - if (DeliverLetter) { + if (Get(LOGIC_DELIVER_RUTOS_LETTER)) { count++; } break; case ITEM_BIG_POE: - if (CanEmptyBigPoes) { + if (Get(LOGIC_CAN_EMPTY_BIG_POES)) { count++; } break; @@ -1123,7 +1126,7 @@ bool Logic::BombchusEnabled() { // TODO: Implement Ammo Drop Setting in place of bombchu drops bool Logic::BombchuRefill() { - return GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant || + return Get(LOGIC_BUY_BOMBCHUS) || Get(LOGIC_COULD_PLAY_BOWLING) || Get(LOGIC_CARPET_MERCHANT) || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON /*_PLUS_BOMBCHU*/)); } @@ -1133,7 +1136,7 @@ bool Logic::HookshotOrBoomerang() { bool Logic::ScarecrowsSong() { return (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) || - (ChildScarecrow && AdultScarecrow); + (Get(LOGIC_CHILD_SCARECROW) && Get(LOGIC_ADULT_SCARECROW)); } bool Logic::BlueFire() { @@ -1213,8 +1216,9 @@ uint8_t Logic::Hearts() { } uint8_t Logic::DungeonCount() { - return DekuTreeClear + DodongosCavernClear + JabuJabusBellyClear + ForestTempleClear + FireTempleClear + - WaterTempleClear + SpiritTempleClear + ShadowTempleClear; + return Get(LOGIC_DEKU_TREE_CLEAR) + Get(LOGIC_DODONGOS_CAVERN_CLEAR) + Get(LOGIC_JABU_JABUS_BELLY_CLEAR) + + Get(LOGIC_FOREST_TEMPLE_CLEAR) + Get(LOGIC_FIRE_TEMPLE_CLEAR) + Get(LOGIC_WATER_TEMPLE_CLEAR) + + Get(LOGIC_SPIRIT_TEMPLE_CLEAR) + Get(LOGIC_SHADOW_TEMPLE_CLEAR); } uint8_t Logic::StoneCount() { @@ -2255,58 +2259,26 @@ void Logic::SetContext(std::shared_ptr _ctx) { ctx = _ctx; } -bool Logic::GetInLogic(LogicVal logicVal) { +bool Logic::Get(LogicVal logicVal) { return inLogic[logicVal]; } -void Logic::SetInLogic(LogicVal logicVal, bool value) { +void Logic::Set(LogicVal logicVal, bool value) { inLogic[logicVal] = value; } +bool Logic::IsFireLoopLocked() { + return ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON); +} + void Logic::Reset(bool resetSaveContext /*= true*/) { if (resetSaveContext) { NewSaveContext(); } StartPerformanceTimer(PT_LOGIC_RESET); memset(inLogic, false, sizeof(inLogic)); - // Settings-dependent variables - IsFireLoopLocked = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || - ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) || - ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON); - - // AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE)*/ false; TODO: AmmoDrop setting - - // Mask quest - CanBorrowMasks = false; - BorrowSkullMask = false; - BorrowSpookyMask = false; - BorrowBunnyHood = false; - BorrowRightMasks = false; - - // Adult logic - FreedEpona = false; - // BigPoe = false; - - // Trade Quest Events - WakeUpAdultTalon = false; - - // Dungeon Clears - DekuTreeClear = false; - DodongosCavernClear = false; - JabuJabusBellyClear = false; - ForestTempleClear = false; - FireTempleClear = false; - WaterTempleClear = false; - SpiritTempleClear = false; - ShadowTempleClear = false; - - // Trial Clears - ForestTrialClear = false; - FireTrialClear = false; - WaterTrialClear = false; - SpiritTrialClear = false; - ShadowTrialClear = false; - LightTrialClear = false; if (resetSaveContext) { // Ocarina C Buttons @@ -2338,136 +2310,28 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { // If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in // vanilla FiT - if (!IsFireLoopLocked && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { + if (!IsFireLoopLocked() && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1); } } - // Bottle Count Bottles = 0; NumBottles = 0; - CanEmptyBigPoes = false; - - // Drops and Bottle Contents Access - NutPot = false; - NutCrate = false; - DekuBabaNuts = false; - StickPot = false; - DekuBabaSticks = false; - BugShrub = false; - WanderingBugs = false; - BugRock = false; - BlueFireAccess = false; - FishGroup = false; - LoneFish = false; - GossipStoneFairy = false; - BeanPlantFairy = false; - ButterflyFairy = false; - FairyPot = false; - FreeFairies = false; - FairyPond = false; - PieceOfHeart = 0; HeartContainer = 0; - /* --- HELPERS, EVENTS, AND LOCATION ACCESS --- */ - /* These are used to simplify reading the logic, but need to be updated - / every time a base value is updated. */ - - ChildScarecrow = false; - AdultScarecrow = false; - - CouldPlayBowling = false; IsChild = false; IsAdult = false; - // CanPlantBean = false; - BigPoeKill = false; BigPoes = 0; BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1; - // Bridge Requirements - BuiltRainbowBridge = false; - - // Other AtDay = false; AtNight = false; if (resetSaveContext) { GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get(); } - // Events - ShowedMidoSwordAndShield = false; - THCouldFree1TorchCarpenter = false; - THCouldFreeDoubleCellCarpenter = false; - TH_CouldFreeDeadEndCarpenter = false; - THCouldRescueSlopeCarpenter = false; - THRescuedAllCarpenters = false; - GF_GateOpen = false; - GtG_GateOpen = false; - DampesWindmillAccess = false; - DrainWell = false; - GoronCityChildFire = false; - GCWoodsWarpOpen = false; - GCDaruniasDoorOpenChild = false; - StopGCRollingGoronAsAdult = false; - CanWaterTempleLowFromHigh = false; - CanWaterTempleLowFromMid = false; - CanWaterTempleMiddle = false; - CanWaterTempleHigh = false; - KakarikoVillageGateOpen = false; - KingZoraThawed = false; - ForestTempleJoelle = false; - ForestTempleBeth = false; - ForestTempleAmy = false; - ForestTempleMeg = false; - FireLoopSwitch = false; - LinksCow = false; - DeliverLetter = false; - ClearMQDCUpperLobbyRocks = false; - LoweredWaterInsideBotw = false; - OpenedWestRoomMQBotw = false; - OpenedMiddleHoleMQBotw = false; - BrokeDeku1FWeb = false; - ClearedMQDekuSERoom = false; - MQDekuWaterRoomTorches = false; - PushedDekuBasementBlock = false; - OpenedLowestGoronCage = false; - OpenedUpperFireShortcut = false; - HitFireTemplePlatform = false; - OpenedFireMQFireMazeDoor = false; - MQForestBlockRoomTargets = false; - ForestCanTwistHallway = false; - ForestClearBelowBowChest = false; - ForestOpenBossCorridor = false; - ShadowTrialFirstChest = false; - MQGTGMazeSwitch = false; - MQGTGRightSideSwitch = false; - GTGPlatformSilverRupees = false; - MQJabuHolesRoomDoor = false; - JabuWestTentacle = false; - JabuEastTentacle = false; - JabuNorthTentacle = false; - LoweredJabuPath = false; - MQJabuLiftRoomCow = false; - MQShadowFloorSpikeRupees = false; - ShadowShortcutBlock = false; - MQWaterStalfosPit = false; - MQWaterDragonTorches = false; - MQWaterB1Switch = false; - // MQWaterPillarSoTBlock = false; - MQWaterOpenedPillarB1 = false; - MQSpiritCrawlBoulder = false; - MQSpiritMapRoomEnemies = false; - MQSpirit3SunsEnemies = false; - Spirit1FSilverRupees = false; - JabuRutoIn1F = false; - DCEyesLit = false; - DCLiftPlatform = false; - DCStairsRoomDoor = false; - DCKilledLowerLizalfos = false; - MQDCBehindFireSwitch = false; - CalculatingAvailableChecks = false; StopPerformanceTimer(PT_LOGIC_RESET); diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 550bb99a2..1d0dee6bc 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -20,167 +20,17 @@ enum class GlitchType { class Logic { public: - bool noVariable = false; - - // Mask Quest - bool CanBorrowMasks = false; - bool BorrowSkullMask = false; - bool BorrowSpookyMask = false; - bool BorrowBunnyHood = false; - bool BorrowRightMasks = false; - - // Adult logic - bool FreedEpona = false; - - // Trade Quest Events - bool WakeUpAdultTalon = false; - - // Dungeon Clears - bool DekuTreeClear = false; - bool DodongosCavernClear = false; - bool JabuJabusBellyClear = false; - bool ForestTempleClear = false; - bool FireTempleClear = false; - bool WaterTempleClear = false; - bool SpiritTempleClear = false; - bool ShadowTempleClear = false; - - // Trial Clears - bool ForestTrialClear = false; - bool FireTrialClear = false; - bool WaterTrialClear = false; - bool SpiritTrialClear = false; - bool ShadowTrialClear = false; - bool LightTrialClear = false; - - // Logical keysanity - bool IsFireLoopLocked = false; - - // Bottle Count uint8_t Bottles = 0; uint8_t NumBottles = 0; - // this event covers if the player can currently empty big poes in logic - bool CanEmptyBigPoes = false; - - // Drops and Bottle Contents Access - bool NutPot = false; - bool NutCrate = false; - bool DekuBabaNuts = false; - bool StickPot = false; - bool DekuBabaSticks = false; - bool BugShrub = false; - bool WanderingBugs = false; - bool BugRock = false; - bool BlueFireAccess = false; - bool FishGroup = false; - bool LoneFish = false; - bool GossipStoneFairy = false; - bool BeanPlantFairy = false; - bool ButterflyFairy = false; - bool FairyPot = false; - bool FreeFairies = false; - bool FairyPond = false; - bool AmmoCanDrop = true; - uint8_t PieceOfHeart = 0; uint8_t HeartContainer = 0; - - bool ChildScarecrow = false; - bool AdultScarecrow = false; - - bool CarpetMerchant = false; - bool CouldPlayBowling = false; bool IsChild = false; bool IsAdult = false; - bool BigPoeKill = false; uint8_t BigPoes = 0; uint8_t BaseHearts = 0; - - // Bridge and LACS Requirements - bool BuiltRainbowBridge = false; - - // Other bool AtDay = false; bool AtNight = false; - // Events - bool ShowedMidoSwordAndShield = false; - bool THCouldFree1TorchCarpenter = false; - bool THCouldFreeDoubleCellCarpenter = false; - bool TH_CouldFreeDeadEndCarpenter = false; - bool THCouldRescueSlopeCarpenter = false; - bool THRescuedAllCarpenters = false; - bool GF_GateOpen = false; - bool GtG_GateOpen = false; - bool DampesWindmillAccess = false; - bool DrainWell = false; - bool GoronCityChildFire = false; - bool GCWoodsWarpOpen = false; - bool GCDaruniasDoorOpenChild = false; - bool StopGCRollingGoronAsAdult = false; - bool CanWaterTempleLowFromHigh = false; - bool CanWaterTempleMiddle = false; - bool CanWaterTempleHigh = false; - bool CanWaterTempleLowFromMid = false; - bool CouldWaterTempleLow = false; - bool CouldWaterTempleMiddle = false; - bool ReachedWaterHighEmblem = false; - bool KakarikoVillageGateOpen = false; - bool KingZoraThawed = false; - bool ForestTempleJoelle = false; - bool ForestTempleBeth = false; - bool ForestTempleAmy = false; - bool ForestTempleMeg = false; - bool FireLoopSwitch = false; - bool LinksCow = false; - bool DeliverLetter = false; - bool ClearMQDCUpperLobbyRocks = false; - bool MQDCBehindFireSwitch = false; - bool LoweredWaterInsideBotw = false; - bool OpenedWestRoomMQBotw = false; - bool OpenedMiddleHoleMQBotw = false; - bool BrokeDeku1FWeb = false; - bool ClearedMQDekuSERoom = false; - bool MQDekuWaterRoomTorches = false; - bool PushedDekuBasementBlock = false; - bool OpenedLowestGoronCage = false; - bool OpenedUpperFireShortcut = false; - bool HitFireTemplePlatform = false; - bool OpenedFireMQFireMazeDoor = false; - bool MQForestBlockRoomTargets = false; - bool ForestCanTwistHallway = false; - bool ForestClearBelowBowChest = false; // a better name that covers both versions would be nice - bool ForestOpenBossCorridor = false; - bool ShadowTrialFirstChest = false; - bool MQGTGMazeSwitch = false; - bool MQGTGRightSideSwitch = false; - bool GTGPlatformSilverRupees = false; - bool MQJabuHolesRoomDoor = false; - bool JabuWestTentacle = false; - bool JabuEastTentacle = false; - bool JabuNorthTentacle = false; - bool LoweredJabuPath = false; - bool MQJabuLiftRoomCow = false; - bool MQShadowFloorSpikeRupees = false; - bool ShadowShortcutBlock = false; - bool MQWaterStalfosPit = false; - bool MQWaterDragonTorches = false; - bool MQWaterB1Switch = false; - // bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD. - bool MQWaterOpenedPillarB1 = false; - bool MQSpiritCrawlBoulder = false; - bool MQSpiritMapRoomEnemies = false; - bool MQSpiritTimeTravelChest = false; - bool MQSpirit3SunsEnemies = false; - bool Spirit1FSilverRupees = false; - bool JabuRutoIn1F = false; - bool DCEyesLit = false; - bool DCLiftPlatform = false; - bool DCStairsRoomDoor = false; - bool DCKilledLowerLizalfos = false; - - /* --- END OF HELPERS AND LOCATION ACCESS --- */ - bool CalculatingAvailableChecks = false; bool ACProcessUndiscoveredExits = false; @@ -253,10 +103,11 @@ class Logic { bool CanUseProjectile(); bool CanBuildRainbowBridge(); bool CanTriggerLACS(); + bool IsFireLoopLocked(); void Reset(bool resetSaveContext = true); void SetContext(std::shared_ptr _ctx); - bool GetInLogic(LogicVal logicVal); - void SetInLogic(LogicVal logicVal, bool remove); + bool Get(LogicVal logicVal); + void Set(LogicVal logicVal, bool remove); void ApplyItemEffect(Item& item, bool state); uint8_t InventorySlot(uint32_t item); void SetUpgrade(uint32_t upgrade, uint8_t level); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c619eb186..c3c1c4942 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -210,6 +210,123 @@ typedef enum { LOGIC_OCARINA_C_LEFT_BUTTON, LOGIC_OCARINA_C_RIGHT_BUTTON, LOGIC_TRIFORCE_PIECES, + LOGIC_CAN_BORROW_MASKS, + LOGIC_BORROW_SKULL_MASK, + LOGIC_BORROW_SPOOKY_MASK, + LOGIC_BORROW_BUNNY_HOOD, + LOGIC_BORROW_RIGHT_MASKS, + LOGIC_FREED_EPONA, + LOGIC_DEKU_TREE_CLEAR, + LOGIC_DODONGOS_CAVERN_CLEAR, + LOGIC_JABU_JABUS_BELLY_CLEAR, + LOGIC_FOREST_TEMPLE_CLEAR, + LOGIC_FIRE_TEMPLE_CLEAR, + LOGIC_WATER_TEMPLE_CLEAR, + LOGIC_SPIRIT_TEMPLE_CLEAR, + LOGIC_SHADOW_TEMPLE_CLEAR, + LOGIC_FOREST_TRIAL_CLEAR, + LOGIC_FIRE_TRIAL_CLEAR, + LOGIC_WATER_TRIAL_CLEAR, + LOGIC_SPIRIT_TRIAL_CLEAR, + LOGIC_SHADOW_TRIAL_CLEAR, + LOGIC_LIGHT_TRIAL_CLEAR, + LOGIC_CAN_EMPTY_BIG_POES, + LOGIC_NUT_POT, + LOGIC_NUT_CRATE, + LOGIC_DEKU_BABA_NUTS, + LOGIC_STICK_POT, + LOGIC_DEKU_BABA_STICKS, + LOGIC_BUG_SHRUB, + LOGIC_WANDERING_BUGS, + LOGIC_BUG_ROCK, + LOGIC_FISH_GROUP, + LOGIC_LONE_FISH, + LOGIC_GOSSIP_STONE_FAIRY, + LOGIC_BEAN_PLANT_FAIRY, + LOGIC_BUTTERFLY_FAIRY, + LOGIC_FAIRY_POT, + LOGIC_FREE_FAIRIES, + LOGIC_FAIRY_POND, + LOGIC_CHILD_SCARECROW, + LOGIC_ADULT_SCARECROW, + LOGIC_CARPET_MERCHANT, + LOGIC_COULD_PLAY_BOWLING, + LOGIC_BIG_POE_KILL, + LOGIC_BUILD_RAINBOW_BRIDGE, + LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, + LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER, + LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER, + LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER, + LOGIC_TH_COULD_FREE_SLOPE_CARPENTER, + LOGIC_TH_RESCUED_ALL_CARPENTERS, + LOGIC_GF_GATE_OPEN, + LOGIC_GTG_GATE_OPEN, + LOGIC_DAMPES_WINDMILL_ACCESS, + LOGIC_DRAIN_WELL, + LOGIC_GORON_CITY_CHILD_FIRE, + LOGIC_GORON_CITY_WOODS_WARP_OPEN, + LOGIC_GORON_CITY_DARUNIAS_DOOR_OPEN_CHILD, + LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT, + LOGIC_DEKU_TREE_1F_BROKE_WEB, + LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, + LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM, + LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, + LOGIC_DC_EYES_LIT, + LOGIC_DC_STAIRS_ROOM_DOOR, + LOGIC_DC_LIFT_PLATFORM, + LOGIC_DC_KILLED_LOWER_LIZALFOS, + LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, + LOGIC_DC_MQ_BEHIND_FIRE_SWITCH, + LOGIC_JABU_RUTO_IN_1F, + LOGIC_JABU_WEST_TENTACLE, + LOGIC_JABU_EAST_TENTACLE, + LOGIC_JABU_NORTH_TENTACLE, + LOGIC_JABU_LOWERED_PATH, + LOGIC_JABU_MQ_HOLES_ROOM_DOOR, + LOGIC_JABU_MQ_LIFT_ROOM_COW, + LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, + LOGIC_FOREST_CAN_TWIST_HALLWAY, + LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, + LOGIC_FOREST_OPEN_BOSS_CORRIDOR, + LOGIC_FOREST_JOELLE, + LOGIC_FOREST_BETH, + LOGIC_FOREST_AMY, + LOGIC_FOREST_MEG, + LOGIC_FIRE_LOOP_SWITCH, + LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE, + LOGIC_FIRE_OPENED_UPPER_SHORTCUT, + LOGIC_FIRE_HIT_PLATFORM, + LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR, + LOGIC_WATER_LOW_FROM_HIGH, + LOGIC_WATER_LOW_FROM_MID, + LOGIC_WATER_MIDDLE, + LOGIC_WATER_HIGH, + LOGIC_WATER_COULD_LOW, + LOGIC_WATER_COULD_MIDDLE, + LOGIC_WATER_REACHED_HIGH_EMBLEM, + LOGIC_WATER_MQ_STALFOS_PIT, + LOGIC_WATER_MQ_DRAGON_TORCHES, + LOGIC_WATER_MQ_B1_SWITCH, + LOGIC_WATER_MQ_B1_OPENED_PILLAR, + LOGIC_SPIRIT_1F_SILVER_RUPEES, + LOGIC_SPIRIT_MQ_CRAWL_BOULDER, + LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, + LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST, + LOGIC_SPIRIT_MQ_3SUNS_ENEMIES, + LOGIC_SHADOW_SHORTCUT_BLOCK, + LOGIC_SHADOW_MQ_FLOOR_SPIKES_RUPEES, + LOGIC_WAKE_UP_ADULT_TALON, + LOGIC_KAKARIKO_GATE_OPEN, + LOGIC_DELIVER_RUTOS_LETTER, + LOGIC_KING_ZORA_THAWED, + LOGIC_LINKS_COW, + LOGIC_BOTW_LOWERED_WATER, + LOGIC_BOTW_MQ_OPENED_WEST_ROOM, + LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE, + LOGIC_GTG_MQ_MAZE_SWITCH, + LOGIC_GTG_MQ_RIGHT_SIDE_SWITCH, + LOGIC_GTG_PLATFORM_SILVER_RUPEES, + LOGIC_SHADOW_TRIAL_FIRST_CHEST, LOGIC_MAX } LogicVal; From 3cf1d654660ef7bb0ce9ae253877bf0ab86615d1 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:35:37 +0200 Subject: [PATCH 71/98] Mod menu V1 (#4962) * Proof of Concept * Fixed saving/loading * Switch sides & add arrow buttons * Update mod_menu.cpp * Remove old mod loading code * Small cleanup * Post-merge fixes * Update mod_menu.cpp * Lots of changes * clang format * Address review * Update SohMenuEnhancements.cpp --- soh/soh/Enhancements/mod_menu.cpp | 239 +++++++++++++++++++++++++ soh/soh/Enhancements/mod_menu.h | 14 ++ soh/soh/OTRGlobals.cpp | 21 +-- soh/soh/SohGui/SohGui.cpp | 5 + soh/soh/SohGui/SohMenuEnhancements.cpp | 9 + 5 files changed, 268 insertions(+), 20 deletions(-) create mode 100644 soh/soh/Enhancements/mod_menu.cpp create mode 100644 soh/soh/Enhancements/mod_menu.h diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp new file mode 100644 index 000000000..427f5b2b4 --- /dev/null +++ b/soh/soh/Enhancements/mod_menu.cpp @@ -0,0 +1,239 @@ +#include "mod_menu.h" +#include "utils/StringHelper.h" +#include +#include "soh/SohGui/SohGui.hpp" +#include "soh/OTRGlobals.h" +#include "soh/resource/type/Skeleton.h" +#include +#include +#include + +std::vector enabledModFiles; +std::vector disabledModFiles; + +#define CVAR_ENABLED_MODS_NAME CVAR_GENERAL("EnabledMods") +#define CVAR_ENABLED_MODS_DEFAULT "" +#define CVAR_ENABLED_MODS_VALUE CVarGetString(CVAR_ENABLED_MODS_NAME, CVAR_ENABLED_MODS_DEFAULT) + +// "|" was chosen as the separator due to +// it being an invalid character in NTFS +// and being rarely used in ext4 +// it is also an ASCII character +// improving portability + +// if being an ASCII character is not a requirement, +// other possible candidates include: +// - U+FFFF: non-character +// - any private use character +#define SEPARATOR "|" + +void SetEnabledModsCVarValue() { + std::string s = ""; + + for (auto& modPath : enabledModFiles) { + s += modPath + SEPARATOR; + } + + // remove trailing separator if present + if (s.length() != 0) { + s.pop_back(); + } + + CVarSetString(CVAR_ENABLED_MODS_NAME, s.c_str()); +} + +std::vector GetEnabledModsFromCVar() { + std::string enabledModsCVarValue = CVAR_ENABLED_MODS_VALUE; + return StringHelper::Split(enabledModsCVarValue, SEPARATOR); +} + +std::vector& GetModFiles(bool enabled) { + return enabled ? enabledModFiles : disabledModFiles; +} + +std::shared_ptr GetArchiveManager() { + return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager(); +} + +void UpdateModFiles(bool init = false) { + if (init) { + enabledModFiles.clear(); + } + disabledModFiles.clear(); + std::vector enabledMods = GetEnabledModsFromCVar(); + std::string modsPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName); + if (modsPath.length() > 0 && std::filesystem::exists(modsPath)) { + if (std::filesystem::is_directory(modsPath)) { + for (const std::filesystem::directory_entry& p : std::filesystem::recursive_directory_iterator( + modsPath, std::filesystem::directory_options::follow_directory_symlink)) { + std::string extension = p.path().extension().string(); + if ( +#ifndef EXCLUDE_MPQ_SUPPORT + StringHelper::IEquals(extension, ".otr") || StringHelper::IEquals(extension, ".mpq") || +#endif + StringHelper::IEquals(extension, ".o2r") || StringHelper::IEquals(extension, ".zip")) { + std::string path = p.path().generic_string(); + bool shouldBeEnabled = std::find(enabledMods.begin(), enabledMods.end(), path) != enabledMods.end(); + + if (shouldBeEnabled) { + if (init) { + enabledModFiles.push_back(path); + GetArchiveManager()->AddArchive(path); + } + } else { + disabledModFiles.push_back(path); + } + } + } + } + } +} + +extern "C" void gfx_texture_cache_clear(); + +void AfterModChange() { + SetEnabledModsCVarValue(); + // TODO: runtime changes + /* + gfx_texture_cache_clear(); + SOH::SkeletonPatcher::ClearSkeletons(); + */ + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + + // disabled mods are always sorted + std::sort(disabledModFiles.begin(), disabledModFiles.end(), [](const std::string& a, const std::string& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), + [](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); }); + }); +} + +void EnableMod(std::string file) { + disabledModFiles.erase(std::find(disabledModFiles.begin(), disabledModFiles.end(), file)); + enabledModFiles.insert(enabledModFiles.begin(), file); + + // TODO: runtime changes + // GetArchiveManager()->AddArchive(file); + AfterModChange(); +} + +void DisableMod(std::string file) { + enabledModFiles.erase(std::find(enabledModFiles.begin(), enabledModFiles.end(), file)); + disabledModFiles.insert(disabledModFiles.begin(), file); + + // TODO: runtime changes + // GetArchiveManager()->RemoveArchive(file); + AfterModChange(); +} + +void DrawModInfo(std::string file) { + ImGui::SameLine(); + ImGui::Text("%s", file.c_str()); +} + +void DrawMods(bool enabled) { + std::vector& selectedModFiles = GetModFiles(enabled); + if (selectedModFiles.empty()) { + return; + } + + bool madeAnyChange = false; + int switchFromIndex = -1; + int switchToIndex = -1; + + for (int i = 0; i < selectedModFiles.size(); i += 1) { + std::string file = selectedModFiles[i]; + if (UIWidgets::StateButton((file + "_left_right").c_str(), enabled ? ICON_FA_ARROW_LEFT : ICON_FA_ARROW_RIGHT, + ImVec2(25, 25), UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + if (enabled) { + DisableMod(file); + } else { + EnableMod(file); + } + } + + // it's not relevant to reorder disabled mods + if (enabled) { + ImGui::SameLine(); + if (i == 0) { + ImGui::BeginDisabled(); + } + if (UIWidgets::StateButton((file + "_up").c_str(), ICON_FA_ARROW_UP, ImVec2(25, 25), + UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + madeAnyChange = true; + switchFromIndex = i; + switchToIndex = i - 1; + } + if (i == 0) { + ImGui::EndDisabled(); + } + + ImGui::SameLine(); + if (i == selectedModFiles.size() - 1) { + ImGui::BeginDisabled(); + } + if (UIWidgets::StateButton((file + "_down").c_str(), ICON_FA_ARROW_DOWN, ImVec2(25, 25), + UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + madeAnyChange = true; + switchFromIndex = i; + switchToIndex = i + 1; + } + if (i == selectedModFiles.size() - 1) { + ImGui::EndDisabled(); + } + } + + DrawModInfo(file); + } + + if (madeAnyChange) { + std::iter_swap(selectedModFiles.begin() + switchFromIndex, selectedModFiles.begin() + switchToIndex); + AfterModChange(); + } +} + +void ModMenuWindow::DrawElement() { + ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); + + const ImVec4 yellow = ImVec4(1, 1, 0, 1); + + ImGui::TextColored( + yellow, "Mods are currently not reloaded at runtime.\nClose and re-open Ship for the changes to take effect."); + + if (UIWidgets::Button("Update", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + UpdateModFiles(); + } + UIWidgets::Tooltip("Re-check the mods folder for new files"); + + if (ImGui::BeginTable("tableMods", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Disabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Enabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + + if (ImGui::BeginChild("Disabled Mods", ImVec2(0, -8))) { + DrawMods(false); + + ImGui::EndChild(); + } + + ImGui::TableNextColumn(); + + if (ImGui::BeginChild("Enabled Mods", ImVec2(0, -8))) { + DrawMods(true); + + ImGui::EndChild(); + } + + ImGui::EndTable(); + } + + ImGui::EndDisabled(); +} + +void ModMenuWindow::InitElement() { + UpdateModFiles(true); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/mod_menu.h b/soh/soh/Enhancements/mod_menu.h new file mode 100644 index 000000000..cb29b4001 --- /dev/null +++ b/soh/soh/Enhancements/mod_menu.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +#ifdef __cplusplus +class ModMenuWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override; + void DrawElement() override; + void UpdateElement() override{}; +}; +#endif \ No newline at end of file diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d306ce228..11dcc220e 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -282,26 +282,7 @@ void OTRGlobals::Initialize() { if (std::filesystem::exists(sohOtrPath)) { OTRFiles.push_back(sohOtrPath); } - std::string patchesPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName); - std::vector patchOTRs = {}; - if (patchesPath.length() > 0 && std::filesystem::exists(patchesPath)) { - if (std::filesystem::is_directory(patchesPath)) { - for (const auto& p : std::filesystem::recursive_directory_iterator( - patchesPath, std::filesystem::directory_options::follow_directory_symlink)) { - if (StringHelper::IEquals(p.path().extension().string(), ".otr") || - StringHelper::IEquals(p.path().extension().string(), ".mpq") || - StringHelper::IEquals(p.path().extension().string(), ".o2r") || - StringHelper::IEquals(p.path().extension().string(), ".zip")) { - patchOTRs.push_back(p.path().generic_string()); - } - } - } - } - std::sort(patchOTRs.begin(), patchOTRs.end(), [](const std::string& a, const std::string& b) { - return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), - [](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); }); - }); - OTRFiles.insert(OTRFiles.end(), patchOTRs.begin(), patchOTRs.end()); + std::unordered_set ValidHashes = { OOT_PAL_MQ, OOT_NTSC_JP_MQ, OOT_NTSC_US_MQ, OOT_PAL_GC_MQ_DBG, OOT_NTSC_US_10, OOT_NTSC_US_11, OOT_NTSC_US_12, OOT_PAL_10, OOT_PAL_11, OOT_NTSC_JP_GC_CE, diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index 8de5478f1..cf9182a62 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -33,6 +33,7 @@ #include "soh/Enhancements/debugger/MessageViewer.h" #include "soh/Notification/Notification.h" #include "soh/Enhancements/TimeDisplay/TimeDisplay.h" +#include "soh/Enhancements/mod_menu.h" namespace SohGui { @@ -72,6 +73,7 @@ std::shared_ptr mStatsWindow; std::shared_ptr mGfxDebuggerWindow; std::shared_ptr mSohMenu; +std::shared_ptr mModMenuWindow; std::shared_ptr mAudioEditorWindow; std::shared_ptr mInputViewer; std::shared_ptr mInputViewerSettings; @@ -134,6 +136,8 @@ void SetupGuiElements() { SPDLOG_ERROR("Could not find input editor window"); }*/ + mModMenuWindow = std::make_shared(CVAR_WINDOW("ModMenu"), "Mod Menu", ImVec2(820, 630)); + gui->AddGuiWindow(mModMenuWindow); mAudioEditorWindow = std::make_shared(CVAR_WINDOW("AudioEditor"), "Audio Editor", ImVec2(820, 630)); gui->AddGuiWindow(mAudioEditorWindow); mInputViewer = std::make_shared(CVAR_WINDOW("InputViewer"), "Input Viewer"); @@ -225,6 +229,7 @@ void Destroy() { mColViewerWindow = nullptr; mActorViewerWindow = nullptr; mCosmeticsEditorWindow = nullptr; + mModMenuWindow = nullptr; mAudioEditorWindow = nullptr; mStatsWindow = nullptr; mConsoleWindow = nullptr; diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 87eb881cb..6e967951d 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1900,6 +1900,15 @@ void SohMenu::AddMenuEnhancements() { .CVar(timer.timeEnable) .Callback([](WidgetInfo& info) { TimeDisplayUpdateDisplayOptions(); }); } + + // Mod Menu + path.sidebarName = "Mod Menu"; + AddSidebarEntry("Enhancements", path.sidebarName, 1); + AddWidget(path, "Popout Mod Menu Window", WIDGET_WINDOW_BUTTON) + .CVar(CVAR_WINDOW("ModMenu")) + .WindowName("Mod Menu") + .HideInSearch(true) + .Options(WindowButtonOptions().Tooltip("Enables the separate Mod Menu Window.")); } } // namespace SohGui From dbbbe0f727236019d5cf2e2f6e2e1e26a9670f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 30 Sep 2025 19:11:31 +0000 Subject: [PATCH 72/98] RT_SHADOW_UMBRELLA_CLIP (#5668) * RT_SHADOW_UMBRELLA_CLIP This is technically a glitch, but offers a novice trick & less requirements Particularly important in doorsanity for child access * feedback, move location to upper since it has multiple paths of access --- .../dungeons/shadow_temple.cpp | 21 +++++++++---------- .../Enhancements/randomizer/randomizerTypes.h | 3 ++- soh/soh/Enhancements/randomizer/settings.cpp | 9 +++++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 6b029899b..ac570543e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -57,17 +57,17 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_HOVER) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_SHADOW_UMBRELLA_CLIP) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_HOVER) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_SHADOW_UMBRELLA_CLIP) || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_HOVER) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_SHADOW_UMBRELLA_CLIP) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_HOVER) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_SHADOW_UMBRELLA_CLIP) || logic->HasItem(RG_GORONS_BRACELET)), //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), @@ -232,24 +232,23 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), - //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. - //Handling the trick here instead of upper as using the block to climb is not a valid method for getting this skull without other tricks to use the block before it is intended - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || - (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return Here(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->CanHitSwitch();});}), - //Assuming the known setup for RT_SHADOW_UMBRELLA, probably possible without sword + shield - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)));}), + //Assuming the known setup for RT_SHADOW_UMBRELLA_HOVER, probably possible without sword + shield + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, []{return ctx->GetTrickOption(RT_SHADOW_UMBRELLA_CLIP) || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_HOVER) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))));}), }); areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA] = Region("Shadow Temple MQ Upper Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, true), + //Assuming the known setup for RT_SHADOW_UMBRELLA_HOVER and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanBreakPots()), }, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c3c1c4942..90cf6c8e1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3766,7 +3766,8 @@ typedef enum { RT_LENS_SHADOW, RT_LENS_SHADOW_PLATFORM, RT_LENS_BONGO, - RT_SHADOW_UMBRELLA, + RT_SHADOW_UMBRELLA_HOVER, + RT_SHADOW_UMBRELLA_CLIP, RT_SHADOW_UMBRELLA_GS, RT_SHADOW_FREESTANDING_KEY, RT_SHADOW_STATUE, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 7872718d6..fe513dcf0 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -969,17 +969,20 @@ void Settings::CreateOptions() { "Shadow Temple Bongo Bongo without Lens of Truth", "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of " "where the eye is."); - OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, + OPT_TRICK(RT_SHADOW_UMBRELLA_HOVER, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "Shadow Temple Stone Umbrella Skip", "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing " "spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); + OPT_TRICK(RT_SHADOW_UMBRELLA_CLIP, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, + "Shadow Temple Stone Umbrella Clip", + "Backflipping as the falling spikes fall clips above without needing any other requirements. " + "Applies to both Vanilla and Master Quest."); OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "Shadow Temple Falling Spikes GS with Hover Boots", "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get " "you on top of the crushing spikes without needing to pull the block. From there, another very precise " "Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both " - "Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to " - "enable \"Shadow Temple Stone Umbrella Skip\"."); + "Vanilla and Master Quest."); OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "Shadow Temple Freestanding Key with Bombchu", "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); From 11a73f88ae97ea781dfe7b6c746dc3c3beb67337 Mon Sep 17 00:00:00 2001 From: Patrick12115 <115201185+Patrick12115@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:16:26 -0400 Subject: [PATCH 73/98] [Enhancement] Allow Slingshot and Bow to break randomized beehives (#5793) * Add slingshot and bow damage checks * Move to Rando and add Logic, hopefully * Missing spacing --- soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp | 5 ++++- soh/soh/Enhancements/randomizer/logic.cpp | 3 ++- soh/soh/Enhancements/randomizer/option_descriptions.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizerTypes.h | 1 + soh/soh/Enhancements/randomizer/settings.cpp | 9 +++++++++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index eccfc3dc3..c5a8b8534 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -55,7 +55,10 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { if ((objComb->collider.base.acFlags & AC_HIT) != 0) { objComb->collider.base.acFlags &= ~AC_HIT; s32 dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags; - if (dmgFlags & 0x4001F866) { + + bool slingBowDmg = RAND_GET_OPTION(RSK_SLINGBOW_BREAK_BEEHIVES) && (dmgFlags & (DMG_ARROW | DMG_SLINGSHOT)); + + if ((dmgFlags & 0x4001F866) && !slingBowDmg) { objComb->unk_1B0 = 1500; } else { ObjComb_Break(objComb, play); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index df0e0a928..90fe83ce9 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1257,7 +1257,8 @@ bool Logic::CanGetNightTimeGS() { } bool Logic::CanBreakUpperBeehives() { - return HookshotOrBoomerang() || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)); + return HookshotOrBoomerang() || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)) || + (ctx->GetOption(RSK_SLINGBOW_BREAK_BEEHIVES) && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT))); } bool Logic::CanBreakLowerBeehives() { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index bd19b3dcb..ce612001b 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -743,6 +743,8 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SUNLIGHT_ARROWS] = "Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. " "Item placement logic will respect this option, so it might be required to use this to progress."; + mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES] = + "Allows Slingshot and Bow to break beehives when Beehive Shuffle is turned on."; mOptionDescriptions[RSK_LOGIC_RULES] = "Glitchless - No glitches are required, but may require some minor tricks. Additional tricks may be enabled " "and disabled below.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 90cf6c8e1..9f105f400 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -5990,6 +5990,7 @@ typedef enum { RSK_MERCHANT_PRICES_AFFORDABLE, RSK_BLUE_FIRE_ARROWS, RSK_SUNLIGHT_ARROWS, + RSK_SLINGBOW_BREAK_BEEHIVES, RSK_ENABLE_BOMBCHU_DROPS, RSK_BOMBCHU_BAG, RSK_LINKS_POCKET, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index fe513dcf0..fc1e95d49 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -305,6 +305,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SUNLIGHT_ARROWS, "Sunlight Arrows", CVAR_RANDOMIZER_SETTING("SunlightArrows"), mOptionDescriptions[RSK_SUNLIGHT_ARROWS]); OPT_U8(RSK_INFINITE_UPGRADES, "Infinite Upgrades", {"Off", "Progressive", "Condensed Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), mOptionDescriptions[RSK_INFINITE_UPGRADES]); OPT_BOOL(RSK_SKELETON_KEY, "Skeleton Key", CVAR_RANDOMIZER_SETTING("SkeletonKey"), mOptionDescriptions[RSK_SKELETON_KEY]); + OPT_BOOL(RSK_SLINGBOW_BREAK_BEEHIVES, "Slingshot/Bow Can Break Beehives", CVAR_RANDOMIZER_SETTING("SlingBowBeehives"), mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES]); OPT_U8(RSK_ITEM_POOL, "Item Pool", {"Plentiful", "Balanced", "Scarce", "Minimal"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ItemPool"), mOptionDescriptions[RSK_ITEM_POOL], WidgetType::Combobox, RO_ITEM_POOL_BALANCED); OPT_U8(RSK_ICE_TRAPS, "Ice Traps", {"Off", "Normal", "Extra", "Mayhem", "Onslaught"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("IceTraps"), mOptionDescriptions[RSK_ICE_TRAPS], WidgetType::Combobox, RO_ICE_TRAPS_NORMAL); // TODO: Remove Double Defense, Progressive Goron Sword @@ -1399,6 +1400,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SUNLIGHT_ARROWS], &mOptions[RSK_INFINITE_UPGRADES], &mOptions[RSK_SKELETON_KEY], + &mOptions[RSK_SLINGBOW_BREAK_BEEHIVES], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = @@ -1665,6 +1667,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SUNLIGHT_ARROWS], &mOptions[RSK_INFINITE_UPGRADES], &mOptions[RSK_SKELETON_KEY], + &mOptions[RSK_SLINGBOW_BREAK_BEEHIVES], }); mOptionGroups[RSG_ITEM_POOL] = OptionGroup( "Item Pool Settings", std::initializer_list({ &mOptions[RSK_ITEM_POOL], &mOptions[RSK_ICE_TRAPS] })); @@ -2542,6 +2545,12 @@ void Settings::UpdateOptionProperties() { } else { mOptions[RSK_BIG_POES_HINT].Enable(); } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_OFF)) { + mOptions[RSK_SLINGBOW_BREAK_BEEHIVES].Enable(); + } else { + mOptions[RSK_SLINGBOW_BREAK_BEEHIVES].Disable( + "This option is disabled because Shuffle Beehives is not enabled."); + } } void Context::FinalizeSettings(const std::set& excludedLocations, From 004ad3aea3ff940b314d2c49e19998269fe7b2b1 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 30 Sep 2025 19:00:05 -0700 Subject: [PATCH 74/98] LUS Bump, Mouse Capture/Cursor Visibility Improvements (#5797) * Bump LUS to include FileDropMgr's new registration system and initial cursor visibility changes. * New LUS ref. * Remove default on for cursor always visible. Add option to camera controls next to enable mouse input for autocapture. Set autocapture on startup. * next LUS * clang again * Add "EnableMouse" CVar check to startup SetAutoCaptureMouse. * Back to LUS main. * Final LUS ref bump. --- libultraship | 2 +- .../controls/SohInputEditorWindow.cpp | 29 ++++++++++++- .../GameInteractor_HookTable.h | 1 - .../Enhancements/randomizer/randomizer.cpp | 26 ++++++++++++ soh/soh/OTRGlobals.cpp | 41 ++++++++----------- 5 files changed, 72 insertions(+), 27 deletions(-) diff --git a/libultraship b/libultraship index 7f737f8be..64f16273a 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 7f737f8be9580980f5a1fe7784d6e1045f0309da +Subproject commit 64f16273a37075bd5d2b5ee6291848370ea7b822 diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index 6fc7f6624..95af88a74 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -1,5 +1,6 @@ #include "SohInputEditorWindow.h" #include +#include "graphic/Fast3D/Fast3dWindow.h" #include "soh/OTRGlobals.h" #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" @@ -15,6 +16,7 @@ using namespace UIWidgets; static WidgetInfo freeLook; static WidgetInfo mouseControl; +static WidgetInfo mouseAutoCapture; static WidgetInfo rightStickOcarina; static WidgetInfo dpadOcarina; static WidgetInfo dpadPause; @@ -1366,6 +1368,9 @@ void SohInputEditorWindow::DrawCameraControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); SohGui::mSohMenu->MenuDrawItem(mouseControl, ImGui::GetContentRegionAvail().x, THEME_COLOR); + cursor = ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); + SohGui::mSohMenu->MenuDrawItem(mouseAutoCapture, ImGui::GetContentRegionAvail().x, THEME_COLOR); Ship::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail()); CVarCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim"), @@ -1914,13 +1919,35 @@ void RegisterInputEditorWidgets() { mouseControl = { .name = "Enable Mouse Controls", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; mouseControl.CVar(CVAR_SETTING("EnableMouse")) + .Callback([](WidgetInfo& info) { + bool enabled = + CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + wnd->SetAutoCaptureMouse(enabled); + }) .Options( CheckboxOptions() .Color(THEME_COLOR) .Tooltip("Allows for using the mouse to control the camera (must enable Free Look), " - "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)")); + "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)\n" + "Press F2 to toggle mouse capture manually.")); SohGui::mSohMenu->AddSearchWidget({ mouseControl, "Settings", "Controls", "Camera Controls" }); + mouseAutoCapture = { .name = "Auto Capture Mouse Input", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + mouseAutoCapture.CVar(CVAR_SETTING("AutoCaptureMouse")) + .Callback([](WidgetInfo& info) { + bool enabled = + CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1); + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + wnd->SetAutoCaptureMouse(enabled); + }) + .Options(CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("When Mouse Controls are enabled, this toggles whether the program will automatically " + "hide the cursor " + "and capture mouse input when closing the menu.")); + SohGui::mSohMenu->AddSearchWidget({ mouseAutoCapture, "Settings", "Controls", "Camera Controls" }); + rightStickOcarina = { .name = "Right Stick Ocarina Playback", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; rightStickOcarina.CVar(CVAR_SETTING("CustomOcarina.RightStick")).Options(CheckboxOptions().Color(THEME_COLOR)); SohGui::mSohMenu->AddSearchWidget({ rightStickOcarina, "Settings", "Controls", "Ocarina Controls" }); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 3ac408e78..2b28198d6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -71,6 +71,5 @@ DEFINE_HOOK(OnFileChooseMain, (void* gameState)); DEFINE_HOOK(OnGenerationCompletion, ()); DEFINE_HOOK(OnSetGameLanguage, ()); -DEFINE_HOOK(OnFileDropped, (std::string filePath)); DEFINE_HOOK(OnAssetAltChange, ()); DEFINE_HOOK(OnKaleidoUpdate, ()); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 49f5fa45a..ac0b7ea4a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -27,6 +27,7 @@ #include #include "draw.h" #include "soh/OTRGlobals.h" +#include "window/FileDropMgr.h" #include "soh/SohGui/UIWidgets.hpp" #include "static_data.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -387,6 +388,29 @@ static const char* frenchRupeeNames[39] = { "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies", }; +bool Rando_HandleSpoilerDrop(char* filePath) { + if (SohUtils::IsStringEmpty(filePath)) { + return false; + } + + try { + std::ifstream stream(filePath); + if (!stream) { + return false; + } + + nlohmann::json json; + stream >> json; + + if (json.contains("version") && json.contains("finalSeed")) { + CVarSetString(CVAR_GENERAL("RandomizerDroppedFile"), filePath); + CVarSetInteger(CVAR_GENERAL("RandomizerNewFileDropped"), 1); + return true; + } + } catch (std::exception& e) {} + return false; +} + Randomizer::Randomizer() { Rando::StaticData::InitItemTable(); Rando::StaticData::InitLocationTable(); @@ -403,6 +427,8 @@ Randomizer::Randomizer() { for (size_t c = 0; c < Rando::StaticData::hintTypeNames.size(); c++) { SpoilerfileHintTypeNameToEnum[Rando::StaticData::hintTypeNames[(HintType)c].GetEnglish(MF_CLEAN)] = (HintType)c; } + + Ship::Context::GetInstance()->GetFileDropMgr()->RegisterDropHandler(Rando_HandleSpoilerDrop); } Randomizer::~Randomizer() { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 11dcc220e..963a5b00d 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -134,7 +134,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" } -void SoH_ProcessDroppedFiles(std::string filePath); +bool SoH_HandleConfigDrop(char* filePath); OTRGlobals* OTRGlobals::Instance; SaveManager* SaveManager::Instance; @@ -327,6 +327,10 @@ void OTRGlobals::Initialize() { std::make_shared(std::vector>({ sohInputEditorWindow })); context->InitWindow(sohFast3dWindow); + context->GetWindow()->SetAutoCaptureMouse(CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && + CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1)); + context->GetWindow()->SetForceCursorVisibility(CVarGetInteger(CVAR_SETTING("CursorVisibility"), 0)); + auto overlay = context->GetInstance()->GetWindow()->GetGui()->GetGameOverlay(); overlay->LoadFont("Press Start 2P", 12.0f, "fonts/PressStart2P-Regular.ttf"); overlay->LoadFont("Fipps", 32.0f, "fonts/Fipps-Regular.otf"); @@ -1270,7 +1274,8 @@ extern "C" void InitOTR() { CVarClear(CVAR_GENERAL("RandomizerNewFileDropped")); CVarClear(CVAR_GENERAL("RandomizerDroppedFile")); // #endregion - GameInteractor::Instance->RegisterGameHook(SoH_ProcessDroppedFiles); + + Ship::Context::GetInstance()->GetFileDropMgr()->RegisterDropHandler(SoH_HandleConfigDrop); RegisterImGuiItemIcons(); @@ -1455,15 +1460,6 @@ extern "C" void Graph_StartFrame() { } } #endif - - auto dropMgr = Ship::Context::GetInstance()->GetFileDropMgr(); - if (dropMgr->FileDropped()) { - std::string filePath = dropMgr->GetDroppedFile(); - if (!filePath.empty()) { - GameInteractor::Instance->ExecuteHooks(filePath); - } - dropMgr->ClearDroppedFile(); - } } void RunCommands(Gfx* Commands, const std::vector>& mtx_replacements) { @@ -2761,26 +2757,21 @@ extern "C" void Gfx_TextureCacheDelete(const uint8_t* texAddr) { } } -void SoH_ProcessDroppedFiles(std::string filePath) { +bool SoH_HandleConfigDrop(char* filePath) { + if (SohUtils::IsStringEmpty(filePath)) { + return false; + } try { std::ifstream configStream(filePath); if (!configStream) { - return; + return false; } nlohmann::json configJson; configStream >> configJson; - // #region SOH [Randomizer] TODO: Refactor spoiler file handling for randomizer - if (configJson.contains("version") && configJson.contains("finalSeed")) { - CVarSetString(CVAR_GENERAL("RandomizerDroppedFile"), filePath.c_str()); - CVarSetInteger(CVAR_GENERAL("RandomizerNewFileDropped"), 1); - return; - } - // #endregion - if (!configJson.contains("CVars")) { - return; + return false; } CVarClearBlock(CVAR_PREFIX_ENHANCEMENT); @@ -2826,17 +2817,19 @@ void SoH_ProcessDroppedFiles(std::string filePath) { uint32_t finalHash = SohUtils::Hash(configJson.dump()); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Configuration Loaded. Hash: %d", finalHash); + return true; } catch (std::exception& e) { SPDLOG_ERROR("Failed to load config file: {}", e.what()); auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file"); - return; + return false; } catch (...) { SPDLOG_ERROR("Failed to load config file"); auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file"); - return; + return false; } + return false; } extern "C" void CheckTracker_RecalculateAvailableChecks() { From 5ed3db0a7ebe21b8adb6f9cda1e4a92b4f8e8fcb Mon Sep 17 00:00:00 2001 From: Eblo <7004497+Eblo@users.noreply.github.com> Date: Tue, 30 Sep 2025 22:00:30 -0400 Subject: [PATCH 75/98] Allow non-ASCII characters on Windows (#5741) --- soh/src/code/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/src/code/main.c b/soh/src/code/main.c index 0a255f48d..769ecc026 100644 --- a/soh/src/code/main.c +++ b/soh/src/code/main.c @@ -1,5 +1,6 @@ #ifdef _WIN32 #include +#include #endif #include "global.h" @@ -52,6 +53,8 @@ int SDL_main(int argc, char** argv) { #ifndef _DEBUG ShowWindow(GetConsoleWindow(), SW_HIDE); #endif + // Allow non-ascii characters for Windows + setlocale(LC_ALL, ".UTF8"); #else //_WIN32 int main(int argc, char** argv) { From e10b882c0811c1d2c08ea400f4e9313c765c0757 Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Wed, 1 Oct 2025 04:03:55 +0200 Subject: [PATCH 76/98] [ADD] - 3D Scenes for pre-render areas (#5804) * Hard removal 2D ones for now * override some scene values for prerender tests (#46) * Adult Link Cloudy * Fix: Child Link Night ToT Exterior * Fix for real now * Tweak: Skybox castle courtyard * WIP - adjusting for patterns * Hooked all code, needs testing * Hookified * Clean up * Update Fog Control * clang * Fix skybox override to only affect 3D pre-rendered scenes Prevent the 3D scene renderer from overriding skyboxes on all scenes Previously, the function was applying skybox changes to every scene, overriding the intended skyboxes throughout the game (Example: Kokiri Forest with a blue sky instead of it's original "greyish" one) Now it only applies custom skybox settings to scenes in the skyboxControlList, preserving original skyboxes for other scenes * Remove commentary and forgot to add Zelda's courtyard skybox * Move code to shipInit. * Early return for VB_SHOULD. * clang * Fix missing ! * Feedback fixes. * clang * Fix CVAR * Modify Skybox for scenes with multiple viewpoints. * setting position change to blend in the "modder stuff can do" * Adressed review * tooltip space missing, oops * InitFunc --------- Co-authored-by: Archez Co-authored-by: Caladius --- .../Graphics/Disable2DBackgrounds.cpp | 161 ++++++++++++++++++ .../GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 + .../game-interactor/GameInteractor_Hooks.h | 1 + .../vanilla-behavior/GIVanillaBehavior.h | 15 ++ soh/soh/SohGui/SohMenuEnhancements.cpp | 7 +- soh/soh/z_play_otr.cpp | 1 + soh/soh/z_scene_otr.cpp | 4 + soh/src/code/z_play.c | 2 + soh/src/code/z_room.c | 4 + soh/src/code/z_vr_box.c | 17 +- 11 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp diff --git a/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp b/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp new file mode 100644 index 000000000..9e9faafac --- /dev/null +++ b/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp @@ -0,0 +1,161 @@ +#include +#include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +#include "macros.h" +#include "variables.h" +} + +#define CVAR_NAME CVAR_ENHANCEMENT("3DSceneRender") +#define CVAR_VALUE CVarGetInteger(CVAR_NAME, 0) + +std::vector fogControlList = { + SCENE_MARKET_ENTRANCE_DAY, + SCENE_MARKET_ENTRANCE_NIGHT, + SCENE_MARKET_ENTRANCE_RUINS, + SCENE_BACK_ALLEY_DAY, + SCENE_BACK_ALLEY_NIGHT, + SCENE_MARKET_DAY, + SCENE_MARKET_NIGHT, + SCENE_MARKET_RUINS, + SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, + SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, + SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, + SCENE_KNOW_IT_ALL_BROS_HOUSE, + SCENE_TWINS_HOUSE, + SCENE_MIDOS_HOUSE, + SCENE_SARIAS_HOUSE, + SCENE_BACK_ALLEY_HOUSE, + SCENE_BAZAAR, + SCENE_KOKIRI_SHOP, + SCENE_GORON_SHOP, + SCENE_ZORA_SHOP, + SCENE_POTION_SHOP_KAKARIKO, + SCENE_POTION_SHOP_MARKET, + SCENE_BOMBCHU_SHOP, + SCENE_HAPPY_MASK_SHOP, + SCENE_LINKS_HOUSE, + SCENE_DOG_LADY_HOUSE, + SCENE_STABLE, + SCENE_IMPAS_HOUSE, + SCENE_CARPENTERS_TENT, + SCENE_GRAVEKEEPERS_HUT, +}; + +std::vector skyboxSceneControlList = { + SCENE_MARKET_ENTRANCE_DAY, + SCENE_MARKET_ENTRANCE_NIGHT, + SCENE_MARKET_ENTRANCE_RUINS, + SCENE_BACK_ALLEY_DAY, + SCENE_BACK_ALLEY_NIGHT, + SCENE_MARKET_DAY, + SCENE_MARKET_NIGHT, + SCENE_MARKET_RUINS, + SCENE_CASTLE_COURTYARD_ZELDA, + SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, + SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, + SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, + SCENE_FOREST_TEMPLE, +}; + +std::vector skyboxIdControlList = { + SKYBOX_BAZAAR, + SKYBOX_HOUSE_LINK, + SKYBOX_MARKET_ADULT, + SKYBOX_MARKET_CHILD_DAY, + SKYBOX_MARKET_CHILD_NIGHT, + SKYBOX_HAPPY_MASK_SHOP, + SKYBOX_HOUSE_KNOW_IT_ALL_BROTHERS, + SKYBOX_HOUSE_OF_TWINS, + SKYBOX_STABLES, + SKYBOX_HOUSE_KAKARIKO, + SKYBOX_KOKIRI_SHOP, + SKYBOX_GORON_SHOP, + SKYBOX_ZORA_SHOP, + SKYBOX_POTION_SHOP_KAKARIKO, + SKYBOX_POTION_SHOP_MARKET, + SKYBOX_HOUSE_RICHARD, + SKYBOX_HOUSE_IMPA, + SKYBOX_TENT, + SKYBOX_HOUSE_MIDO, + SKYBOX_HOUSE_SARIA, + SKYBOX_HOUSE_ALLEY, +}; + +void Register3DPreRenderedScenes() { + COND_HOOK(AfterSceneCommands, CVAR_VALUE, [](int16_t sceneNum) { + // Check if this scene is in the skyboxControlList + bool shouldControlSkybox = false; + for (const auto& scene : skyboxSceneControlList) { + if (sceneNum == scene) { + shouldControlSkybox = true; + break; + } + } + + if (shouldControlSkybox) { + // Add a skybox on scenes from skyboxSceneControlList + gPlayState->envCtx.skyboxDisabled = false; + + // Replace skybox with normal sky + gPlayState->skyboxId = SKYBOX_NORMAL_SKY; + // Apply the always cloudy skybox as an adult for Temple of Time and the Market + if (sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS || sceneNum == SCENE_MARKET_RUINS || + sceneNum == SCENE_MARKET_ENTRANCE_RUINS) { + gWeatherMode = 3; + } + } + }); + + COND_HOOK(OnPlayDrawBegin, CVAR_VALUE, []() { + if (!CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0)) { + return; + } + + for (auto& scene : fogControlList) { + if (scene == gPlayState->sceneNum) { + if ((HREG(80) != 10) || (HREG(82) != 0)) { + // Furthest possible fog and zFar + gPlayState->view.zFar = 12800; + gPlayState->lightCtx.fogNear = 996; // Set to 1000 to complete disable fog entirely + gPlayState->lightCtx.fogFar = 12800; + // General gray fog color + gPlayState->lightCtx.fogColor[0] = 100; + gPlayState->lightCtx.fogColor[1] = 100; + gPlayState->lightCtx.fogColor[2] = 100; + } + break; + } + } + }); + REGISTER_VB_SHOULD(VB_DRAW_2D_BACKGROUND, { + if (CVAR_VALUE) { + *should = false; + return; + } + }); + + REGISTER_VB_SHOULD(VB_LOAD_SKYBOX, { + if (!gPlayState) { + return; + } + + if (!CVAR_VALUE) { + return; + } + + for (auto& skybox : skyboxIdControlList) { + if (gPlayState->skyboxCtx.skyboxId == skybox) { + gPlayState->skyboxCtx.unk_140 = 0; + *should = false; + return; + } + } + }); +} + +static RegisterShipInitFunc PreRender3DInitFunc(Register3DPreRenderedScenes, { CVAR_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 2b28198d6..b5b1cfbfe 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -42,6 +42,7 @@ DEFINE_HOOK(OnPlayerFirstPersonControl, (Player * player)); DEFINE_HOOK(OnPlayerProcessStick, ()); DEFINE_HOOK(OnPlayerShieldControl, (float_t * sp50, float_t* sp54)); DEFINE_HOOK(OnPlayDestroy, ()); +DEFINE_HOOK(OnPlayDrawBegin, ()); DEFINE_HOOK(OnPlayDrawEnd, ()); DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list originalArgs)); DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index f69cc29af..f374aa2d7 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -186,6 +186,10 @@ void GameInteractor_ExecuteOnPlayDestroy() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnPlayDrawBegin() { + GameInteractor::Instance->ExecuteHooks(); +} + void GameInteractor_ExecuteOnPlayDrawEnd() { GameInteractor::Instance->ExecuteHooks(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index a6f1563f2..e22d12dbd 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -45,6 +45,7 @@ void GameInteractor_ExecuteOnPlayerShieldControl(float_t* sp50, float_t* sp54); void GameInteractor_ExecuteOnPlayerProcessStick(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnPlayDestroy(); +void GameInteractor_ExecuteOnPlayDrawBegin(); void GameInteractor_ExecuteOnPlayDrawEnd(); bool GameInteractor_Should(GIVanillaBehavior flag, uint32_t result, ...); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 6eada52f6..cc32829b7 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2257,6 +2257,20 @@ typedef enum { // #### `result` // ```c + // CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0) + // ``` + // #### `args` + // - None + VB_DRAW_2D_BACKGROUND, + + // #### `result` + // ```c + // CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0) + // ``` + // #### `args` + // - None + VB_LOAD_SKYBOX, + // true // ``` // #### `args` @@ -2270,6 +2284,7 @@ typedef enum { // #### `args` // - `*Player` VB_SET_STATIC_FLOOR_TYPE, + } GIVanillaBehavior; #endif diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 6e967951d..2f37291af 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -555,12 +555,17 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip( "Disables Grottos rotating with the Camera. To be used in conjuction with mods that want to " "replace grottos with 3D objects.")); + AddWidget(path, "Disable 2D Pre-Rendered Scenes", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("3DSceneRender")) + .RaceDisable(false) + .Options(CheckboxOptions().Tooltip("Disables 2D pre-rendered backgrounds. Enable this when using a mod that " + "implements 3D backdrops for these areas.\n" + "Requires Scene Change to alter.")); AddWidget(path, "Ingame Text Spacing: %d", WIDGET_CVAR_SLIDER_INT) .CVar(CVAR_ENHANCEMENT("TextSpacing")) .RaceDisable(false) .Options(IntSliderOptions().Min(4).Max(6).DefaultValue(6).Tooltip( "Space between text characters (useful for HD font textures).")); - AddWidget(path, "Models & Textures", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Disable LOD", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("DisableLOD")) diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 23e61261c..5055b969b 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -79,6 +79,7 @@ void OTRPlay_InitScene(PlayState* play, s32 spawn) { YREG(15) = 0; gSaveContext.worldMapArea = 0; OTRScene_ExecuteCommands(play, (SOH::Scene*)play->sceneSegment); + GameInteractor_ExecuteAfterSceneCommands(play->sceneNum); Play_InitEnvironment(play, play->skyboxId); /* auto data = static_cast(Ship::Context::GetInstance() diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp index b4f8a29e8..1baf6151d 100644 --- a/soh/soh/z_scene_otr.cpp +++ b/soh/soh/z_scene_otr.cpp @@ -472,6 +472,10 @@ extern "C" s32 OTRfunc_800973FC(PlayState* play, RoomContext* roomCtx) { gSegments[3] = VIRTUAL_TO_PHYSICAL(roomCtx->unk_34); OTRScene_ExecuteCommands(play, (SOH::Scene*)roomCtx->roomToLoad); + if (!GameInteractor_Should(VB_DRAW_2D_BACKGROUND, true)) { + play->envCtx.skyboxDisabled = false; + } + Player_SetBootData(play, GET_PLAYER(play)); Actor_SpawnTransitionActors(play, &play->actorCtx); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index dfc832fc7..b1a714dcb 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1390,6 +1390,8 @@ void Play_Draw(PlayState* play) { Gfx_SetupFrame(gfxCtx, 0, 0, 0); if ((HREG(80) != 10) || (HREG(82) != 0)) { + GameInteractor_ExecuteOnPlayDrawBegin(); + POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP); POLY_XLU_DISP = Play_SetFog(play, POLY_XLU_DISP); diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 60fa3f0ff..493752555 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -5,6 +5,7 @@ #include "global.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #include @@ -256,6 +257,9 @@ s32 swapAndConvertJPEG(void* data) { void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode, u16 tlutCount, f32 offsetX, f32 offsetY) { + if (!GameInteractor_Should(VB_DRAW_2D_BACKGROUND, true)) { + return; + } Gfx* gfx = *gfxP; uObjBg* bg; diff --git a/soh/src/code/z_vr_box.c b/soh/src/code/z_vr_box.c index c11db1605..f03f9dc7f 100644 --- a/soh/src/code/z_vr_box.c +++ b/soh/src/code/z_vr_box.c @@ -71,6 +71,9 @@ #include "assets/textures/skyboxes/vr_holy1_static.h" #include "assets/textures/skyboxes/vr_holy1_pal_static.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" + u32 D_8012AC90[4] = { 0x00000000, 0x00010000, @@ -449,17 +452,23 @@ void func_800AF178(SkyboxContext* skyboxCtx, s32 arg1) { void LoadSkyboxTex(SkyboxContext* skyboxCtx, int segmentIndex, int imageIndex, char* tex, int width, int height, int offsetW, int offsetH) { - skyboxCtx->textures[segmentIndex][imageIndex] = tex; + if (GameInteractor_Should(VB_LOAD_SKYBOX, true)) { + skyboxCtx->textures[segmentIndex][imageIndex] = tex; + } } void LoadSkyboxTexAtOffset(SkyboxContext* skyboxCtx, int segmentIndex, int imageIndex, char* tex, int width, int height, int offset) { - skyboxCtx->textures[segmentIndex][imageIndex] = tex; + if (GameInteractor_Should(VB_LOAD_SKYBOX, true)) { + skyboxCtx->textures[segmentIndex][imageIndex] = tex; + } } void LoadSkyboxPalette(SkyboxContext* skyboxCtx, int paletteIndex, char* palTex, int width, int height) { - skyboxCtx->palettes[paletteIndex] = palTex; - skyboxCtx->palette_size = width * height; + if (GameInteractor_Should(VB_LOAD_SKYBOX, true)) { + skyboxCtx->palettes[paletteIndex] = palTex; + skyboxCtx->palette_size = width * height; + } } static const char* sSBVRFine0Tex[] = { gSunriseSkybox1Tex, gSunriseSkybox2Tex, gSunriseSkybox3Tex, gSunriseSkybox4Tex, From 545cc396b4340035ff1b42b68a4b50ef44772d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 2 Oct 2025 18:24:18 +0000 Subject: [PATCH 77/98] Treesanity (#5541) * treesanity co-authored-by: turbofist * market tree at night * NL Trees * remove LUSLOG * feedback * format * golden skulltula tree qol * post-rebase * trust -129 * remove tree graphic, crate csmc * format * feedback * ObjectExtension --- .../vanilla-behavior/GIVanillaBehavior.h | 17 ++ .../hint_list/hint_list_exclude_overworld.cpp | 24 ++ .../randomizer/3drando/item_pool.cpp | 14 +- .../Enhancements/randomizer/ShuffleTrees.cpp | 265 ++++++++++++++++++ soh/soh/Enhancements/randomizer/context.cpp | 5 +- soh/soh/Enhancements/randomizer/location.cpp | 18 ++ soh/soh/Enhancements/randomizer/location.h | 8 + .../overworld/castle_grounds.cpp | 12 +- .../overworld/hyrule_field.cpp | 48 ++++ .../location_access/overworld/kakariko.cpp | 3 +- .../overworld/lon_lon_ranch.cpp | 3 +- .../location_access/overworld/market.cpp | 1 + .../overworld/zoras_fountain.cpp | 3 +- .../location_access/overworld/zoras_river.cpp | 3 +- soh/soh/Enhancements/randomizer/logic.cpp | 4 + soh/soh/Enhancements/randomizer/logic.h | 1 + .../randomizer/option_descriptions.cpp | 5 + .../Enhancements/randomizer/randomizer.cpp | 84 ++++++ soh/soh/Enhancements/randomizer/randomizer.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 82 ++++++ .../randomizer/randomizer_check_objects.cpp | 4 + .../randomizer/randomizer_check_tracker.cpp | 13 +- .../Enhancements/randomizer/randomizer_inf.h | 63 +++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 + soh/soh/Enhancements/randomizer/static_data.h | 1 + .../actors/ovl_En_Wood02/z_en_wood02.c | 27 +- 26 files changed, 687 insertions(+), 25 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleTrees.cpp diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index cc32829b7..a0c2629d9 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2155,6 +2155,23 @@ typedef enum { // - `*EnWood02` VB_TREE_DROP_COLLECTIBLE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_SETUP_DRAW, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_TREE_DROP_ITEM, + + // #### `result` // ```c // true // ``` diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 5fcb213ff..2fe5992bf 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2102,6 +2102,30 @@ void StaticData::HintTable_Init_Exclude_Overworld() { /*german*/ "Man erzählt sich, daß eine #Kiste im Labor am See# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans un laboratoire# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_TREE_HYRULE_FIELD] = + HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_MARKET] = + HintText(CustomMessage("They say that a #tree in Hyrule Market# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_HYRULE_CASTLE] = + HintText(CustomMessage("They say that a #tree in Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_ZORAS_RIVER] = + HintText(CustomMessage("They say that a #tree in Zora's River# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_ZORAS_FOUNTAIN] = + HintText(CustomMessage("They say that a #tree in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + hintTextTable[RHT_TREE_LON_LON_RANCH] = + HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); // clang-format on } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 28f05010e..cd179676d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -604,17 +604,23 @@ void GenerateItemPool() { ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive); + // Shuffle Trees + bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES); + PlaceItemsForType(RCTYPE_TREE, treesActive, false); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) { + PlaceItemsForType(RCTYPE_NLTREE, treesActive, false); + } + // Shuffle Crates bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); - bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && - (ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL)); bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive); - PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive); PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) { + PlaceItemsForType(RCTYPE_NLCRATE, overworldCratesActive, dungeonCratesActive); + } auto fsMode = ctx->GetOption(RSK_FISHSANITY); if (fsMode.IsNot(RO_FISHSANITY_OFF)) { diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp new file mode 100644 index 000000000..418468e30 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -0,0 +1,265 @@ +#include +#include "soh_assets.h" +#include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" + +extern "C" { +#include "variables.h" +#include "src/overlays/actors/ovl_En_Wood02/z_en_wood02.h" +#include "objects/object_wood02/object_wood02.h" +#include "soh/Enhancements/enhancementTypes.h" +extern PlayState* gPlayState; +void EnWood02_Draw(Actor*, PlayState*); +} + +static Gfx* D_80B3BF54[] = { + (Gfx*)object_wood02_DL_0078D0, (Gfx*)object_wood02_DL_007CA0, (Gfx*)object_wood02_DL_0080D0, + (Gfx*)object_wood02_DL_000090, (Gfx*)object_wood02_DL_000340, (Gfx*)object_wood02_DL_000340, + (Gfx*)object_wood02_DL_000700, +}; + +static Gfx* D_80B3BF70[] = { + (Gfx*)object_wood02_DL_007968, + (Gfx*)object_wood02_DL_007D38, + (Gfx*)object_wood02_DL_0081A8, + NULL, + NULL, + NULL, + (Gfx*)object_wood02_DL_007AD0, + (Gfx*)object_wood02_DL_007E20, + (Gfx*)object_wood02_DL_008350, + (Gfx*)object_wood02_DL_000160, + (Gfx*)object_wood02_DL_000440, + (Gfx*)object_wood02_DL_000700, +}; + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) { + const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); + if (treeIdentity == nullptr) { + return false; + } + + // Don't pull randomized item if tree isn't randomized or is already checked + return IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get() && + !Flags_GetRandomizerInf(treeIdentity->randomizerInf) && treeIdentity->randomizerCheck != RC_UNKNOWN_CHECK; +} + +extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { + GetItemCategory getItemCategory; + GetItemEntry smallCrateItem; + auto treeActor = (EnWood02*)thisx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + int isVanilla = + csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); + if (treeIdentity == nullptr) { + return; + } + + if (isVanilla || treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + getItemCategory = ITEM_CATEGORY_JUNK; + } else { + smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE); + getItemCategory = smallCrateItem.getItemCategory; + + // If they have bombchus, don't consider the bombchu item major + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && + ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || + (smallCrateItem.modIndex == MOD_NONE && + (smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 || + smallCrateItem.getItemId == GI_BOMBCHUS_20)))) { + getItemCategory = ITEM_CATEGORY_JUNK; + // If it's a bottle and they already have one, consider the item lesser + } else if ((smallCrateItem.modIndex == MOD_RANDOMIZER && + smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && + smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) || + (smallCrateItem.modIndex == MOD_NONE && + (smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) { + if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { + getItemCategory = ITEM_CATEGORY_LESSER; + } + } + } + + GraphicsContext* gfxCtx = play->state.gfxCtx; + OPEN_DISPS(gfxCtx); + Matrix_Push(); + + // Change texture + switch (getItemCategory) { + case ITEM_CATEGORY_MAJOR: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL); + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL); + break; + case ITEM_CATEGORY_SMALL_KEY: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL); + break; + case ITEM_CATEGORY_BOSS_KEY: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL); + break; + case ITEM_CATEGORY_LESSER: + Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); + switch (smallCrateItem.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL); + break; + default: + Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL); + break; + } + case ITEM_CATEGORY_JUNK: + default: + Matrix_Scale(0.04, 0.02, 0.04, MTXMODE_APPLY); + Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL); + break; + } + + Matrix_Pop(); + CLOSE_DISPS(gfxCtx); +} + +void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) { + const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); + if (treeIdentity == nullptr) { + return; + } + + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &treeActor->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = treeIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 0.0f; + item00->actor.world.pos.y += 120.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); + // clear randomizerCheck to prevent multiple bonks, + // reloading area without collecting drop won't persist this + treeIdentity->randomizerCheck = RC_UNKNOWN_CHECK; +} + +void EnWood02_RandomizerInit(void* actorRef) { + EnWood02* treeActor = static_cast(actorRef); + if (treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { + auto treeIdentity = OTRGlobals::Instance->gRandomizer->IdentifyTree( + gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z); + ObjectExtension::GetInstance().Set(actorRef, std::move(treeIdentity)); + } +} + +void RegisterShuffleTrees() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get(); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegister, EnWood02_RandomizerInit); + + COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + EnWood02_RandomizerDraw(&treeActor->actor, gPlayState); + } + }); + + COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState); + // QoL, drop golden skulltula alongside item + if ((treeActor->unk_14C < 0 || treeActor->unk_14C >= 0x64) && treeActor->actor.home.rot.z != 0) { + Vec3f dropsSpawnPt = treeActor->actor.world.pos; + dropsSpawnPt.y += 200.0f; + treeActor->actor.home.rot.z &= 0x1FFF; + treeActor->actor.home.rot.z |= 0xE000; + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, + dropsSpawnPt.z, 0, treeActor->actor.world.rot.y, 0, treeActor->actor.home.rot.z, true); + treeActor->actor.home.rot.z = 0; + } + *should = false; + } + }); +} + +void Rando::StaticData::RegisterTreeLocations() { + // clang-format off + // Trees + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_MARKET_TREE] = Location::Tree(RC_MARKET_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREE)); + locationTable[RC_HC_NEAR_GUARDS_TREE_1] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1209, 2242), "Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_1)); + locationTable[RC_HC_NEAR_GUARDS_TREE_2] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(943, 2051), "Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_2)); + locationTable[RC_HC_NEAR_GUARDS_TREE_3] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(827, 1428), "Tree Near Guards 3", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_3)); + locationTable[RC_HC_NEAR_GUARDS_TREE_4] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(421, 1397), "Tree Near Guards 4", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_4)); + locationTable[RC_HC_NEAR_GUARDS_TREE_5] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-73, 1459), "Tree Near Guards 5", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_5)); + locationTable[RC_HC_NEAR_GUARDS_TREE_6] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1494, 2108), "Tree Near Guards 6", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_6)); + locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "HC GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE)); + locationTable[RC_HC_GROTTO_TREE] = Location::Tree(RC_HC_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(924, 872), "Tree Near Storms Grotto", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GROTTO_TREE)); + locationTable[RC_HC_NL_TREE_1] = Location::NLTree(RC_HC_NL_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-331, 1438), "NL Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_1)); + locationTable[RC_HC_NL_TREE_2] = Location::NLTree(RC_HC_NL_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1022, 1444), "NL Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_2)); + locationTable[RC_HF_NEAR_KAK_TREE] = Location::Tree(RC_HF_NEAR_KAK_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3276, 971), "Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_TREE)); + locationTable[RC_HF_NEAR_KAK_SMALL_TREE] = Location::Tree(RC_HF_NEAR_KAK_SMALL_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2076, -91), "Small Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_SMALL_TREE)); + locationTable[RC_HF_NEAR_MARKET_TREE_1] = Location::Tree(RC_HF_NEAR_MARKET_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1041, 1022), "Tree Near HC Entrance Grotto 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_1)); + locationTable[RC_HF_NEAR_MARKET_TREE_2] = Location::Tree(RC_HF_NEAR_MARKET_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1244, 819), "Tree Near HC Entrance Grotto 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_2)); + locationTable[RC_HF_NEAR_MARKET_TREE_3] = Location::Tree(RC_HF_NEAR_MARKET_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1448, 620), "Tree Near HC Entrance Grotto 3", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_3)); + locationTable[RC_HF_NEAR_LLR_TREE] = Location::Tree(RC_HF_NEAR_LLR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1907, 5409), "Tree Outside Lon Lon Ranch", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LLR_TREE)); + locationTable[RC_HF_NEAR_LH_TREE] = Location::Tree(RC_HF_NEAR_LH_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4377, 13662), "Tree Outside Lake Hylia", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LH_TREE)); + locationTable[RC_HF_CHILD_NEAR_GV_TREE] = Location::Tree(RC_HF_CHILD_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6270, 8579), "Child Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NEAR_GV_TREE)); + locationTable[RC_HF_ADULT_NEAR_GV_TREE] = Location::Tree(RC_HF_ADULT_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6241, 7097), "Adult Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ADULT_NEAR_GV_TREE)); + locationTable[RC_HF_NEAR_ZR_TREE] = Location::Tree(RC_HF_NEAR_ZR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3117, 4239), "Tree Outside Zora's River", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_ZR_TREE)); + locationTable[RC_HF_NORTHWEST_TREE_1] = Location::Tree(RC_HF_NORTHWEST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4777, 136), "Tree in Northwest 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_1)); + locationTable[RC_HF_NORTHWEST_TREE_2] = Location::Tree(RC_HF_NORTHWEST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4188, 263), "Tree in Northwest 2", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_2)); + locationTable[RC_HF_NORTHWEST_TREE_3] = Location::Tree(RC_HF_NORTHWEST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5000, -147), "Tree in Northwest 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_3)); + locationTable[RC_HF_NORTHWEST_TREE_4] = Location::Tree(RC_HF_NORTHWEST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4463, -182), "Tree in Northwest 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_4)); + locationTable[RC_HF_NORTHWEST_TREE_5] = Location::Tree(RC_HF_NORTHWEST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5262, 398), "Tree in Northwest 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_5)); + locationTable[RC_HF_NORTHWEST_TREE_6] = Location::Tree(RC_HF_NORTHWEST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4391, 891), "Tree in Northwest 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_6)); + locationTable[RC_HF_EAST_TREE_1] = Location::Tree(RC_HF_EAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3817, 7119), "Tree in East 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_1)); + locationTable[RC_HF_EAST_TREE_2] = Location::Tree(RC_HF_EAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(4365, 7182), "Tree in East 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_2)); + locationTable[RC_HF_EAST_TREE_3] = Location::Tree(RC_HF_EAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3837, 7479), "Tree in East 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_3)); + locationTable[RC_HF_EAST_TREE_4] = Location::Tree(RC_HF_EAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3377, 7201), "Tree in East 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_4)); + locationTable[RC_HF_EAST_TREE_5] = Location::Tree(RC_HF_EAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3408, 6676), "Tree in East 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_5)); + locationTable[RC_HF_EAST_TREE_6] = Location::Tree(RC_HF_EAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3935, 6279), "Tree in East 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_6)); + locationTable[RC_HF_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(915, 12557), "Tree in Southeast 1", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_1)); + locationTable[RC_HF_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(350, 11605), "Tree in Southeast 2", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_2)); + locationTable[RC_HF_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(470, 12494), "Tree in Southeast 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_3)); + locationTable[RC_HF_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(614, 12357), "Tree in Southeast 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_4)); + locationTable[RC_HF_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1114, 12156), "Tree in Southeast 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_5)); + locationTable[RC_HF_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(549, 11204), "Tree in Southeast 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_6)); + locationTable[RC_HF_SOUTHEAST_TREE_7] = Location::Tree(RC_HF_SOUTHEAST_TREE_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(49, 11405), "Tree in Southeast 7", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_7)); + locationTable[RC_HF_SOUTHEAST_TREE_8] = Location::Tree(RC_HF_SOUTHEAST_TREE_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-29, 12005), "Tree in Southeast 8", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_8)); + locationTable[RC_HF_SOUTHEAST_TREE_9] = Location::Tree(RC_HF_SOUTHEAST_TREE_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1514,13157), "Tree in Southeast 9", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_9)); + locationTable[RC_HF_SOUTHEAST_TREE_10] = Location::Tree(RC_HF_SOUTHEAST_TREE_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-509,12954), "Tree in Southeast 10", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_10)); + locationTable[RC_HF_SOUTHEAST_TREE_11] = Location::Tree(RC_HF_SOUTHEAST_TREE_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-430,12354), "Tree in Southeast 11", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_11)); + locationTable[RC_HF_SOUTHEAST_TREE_12] = Location::Tree(RC_HF_SOUTHEAST_TREE_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(69,12153), "Tree in Southeast 12", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_12)); + locationTable[RC_HF_SOUTHEAST_TREE_13] = Location::Tree(RC_HF_SOUTHEAST_TREE_13, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-129,12554), "Tree in Southeast 13", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_13)); + locationTable[RC_HF_SOUTHEAST_TREE_14] = Location::Tree(RC_HF_SOUTHEAST_TREE_14, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(950,11545), "Tree in Southeast 14", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_14)); + locationTable[RC_HF_SOUTHEAST_TREE_15] = Location::Tree(RC_HF_SOUTHEAST_TREE_15, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(949,12205), "Tree in Southeast 15", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_15)); + locationTable[RC_HF_SOUTHEAST_TREE_16] = Location::Tree(RC_HF_SOUTHEAST_TREE_16, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(469,13154), "Tree in Southeast 16", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_16)); + locationTable[RC_HF_SOUTHEAST_TREE_17] = Location::Tree(RC_HF_SOUTHEAST_TREE_17, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(535,12957), "Tree in Southeast 17", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_17)); + locationTable[RC_HF_SOUTHEAST_TREE_18] = Location::Tree(RC_HF_SOUTHEAST_TREE_18, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1515,12497), "Tree in Southeast 18", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_18)); + locationTable[RC_HF_SOUTHEAST_TREE_19] = Location::Tree(RC_HF_SOUTHEAST_TREE_19, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-786,11293), "Tree in Southeast 19", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_19)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1535, 11943), "Child Tree in Southeast Corner 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2135,11883), "Child Tree in Southeast Corner 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2134,12543), "Child Tree in Southeast Corner 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1734,11542), "Child Tree in Southeast Corner 4", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1234,11743), "Child Tree in Southeast Corner 5", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5)); + locationTable[RC_HF_CHILD_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1155,12343), "Child Tree in Southeast Corner 6", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6)); + locationTable[RC_HF_TEKTITE_GROTTO_TREE] = Location::Tree(RC_HF_TEKTITE_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4976, 2812), "Tektite Grotto Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_TEKTITE_GROTTO_TREE)); + locationTable[RC_ZF_TREE] = Location::Tree(RC_ZF_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(186, 2222), "Tree in Zora's Fountain", RHT_TREE_ZORAS_FOUNTAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_TREE)); + locationTable[RC_ZR_TREE] = Location::Tree(RC_ZR_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1690, 554), "Tree in Zoras River", RHT_TREE_ZORAS_RIVER, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_TREE)); + locationTable[RC_KAK_TREE] = Location::Tree(RC_KAK_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-860, 522), "Kakariko GS Tree", RHT_TREE_KAKARIKO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_TREE)); + locationTable[RC_LLR_TREE] = Location::Tree(RC_LLR_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(1309, -2241), "Lon Lon Ranch GS Tree", RHT_TREE_LON_LON_RANCH, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TREE)); + // clang-format on +} + +static ObjectExtension::Register RegisterPotIdentity; +static RegisterShipInitFunc registerShuffleTrees(RegisterShuffleTrees, { "IS_RANDO" }); +static RegisterShipInitFunc registerShuffleTreeLocations(Rando::StaticData::RegisterTreeLocations); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index bd011d654..05e459198 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -193,9 +193,12 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) || (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || - !mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) || + mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || + (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || + (location.GetRCType() == RCTYPE_NLTREE && + (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index 6c27e3aef..e23c91d2a 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -567,6 +567,24 @@ Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQ false, collectionCheck }; } +Rando::Location Rando::Location::Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_TREE, area_, ACTOR_EN_WOOD02, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_NLTREE, area_, ACTOR_EN_WOOD02, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index f99499652..9c565344f 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -246,6 +246,14 @@ class Location { RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index e326baba1..09ae6443f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -24,7 +24,7 @@ void RegionTable_Init_CastleGrounds() { }, { //Locations LOCATION(RC_HC_MALON_EGG, true), - LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), + LOCATION(RC_HC_GS_TREE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), @@ -33,6 +33,16 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_NL_TREE_1, false), + LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index bad6215a8..6c23dbcb8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -62,6 +62,54 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_NEAR_KF_GRASS_10, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_KF_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_HF_NEAR_KF_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_HF_NEAR_LLR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_LH_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_NEAR_GV_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_ADULT_NEAR_GV_TREE, logic->IsAdult && logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_ZR_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_KAK_SMALL_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NEAR_MARKET_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_NORTHWEST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_EAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_1, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_2, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_3, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_4, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_5, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_6, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_7, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_8, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_9, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_10, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_11, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_12, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_13, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_14, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_15, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_16, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_17, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_18, logic->CanBonkTrees()), + LOCATION(RC_HF_SOUTHEAST_TREE_19, logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_1, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_2, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_3, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_4, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), }, { //Exits Entrance(RR_LW_BRIDGE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 1373129e7..cb6bb78a1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -22,7 +22,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), - LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS() && logic->CanBonkTrees()), LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()), @@ -59,6 +59,7 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_FENCE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index df143c2da..4bfae2f1e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -12,7 +12,7 @@ void RegionTable_Init_LonLonRanch() { }, { //Locations LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), - LOCATION(RC_LLR_GS_TREE, logic->IsChild), + LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), @@ -24,6 +24,7 @@ void RegionTable_Init_LonLonRanch() { LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_NEAR_TREE_CRATE, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_LLR_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index b82a051f0..982601b3c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -27,6 +27,7 @@ void RegionTable_Init_Market() { LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), + LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_MARKET_ENTRANCE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index 178b5ecf9..0a8a1d2bc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -11,7 +11,7 @@ void RegionTable_Init_ZorasFountain() { EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), }, { //Locations - LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -23,6 +23,7 @@ void RegionTable_Init_ZorasFountain() { LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index be1d245aa..bfd228523 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), @@ -20,6 +20,7 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 90fe83ce9..d1e3807f5 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1155,6 +1155,10 @@ bool Logic::CanBreakSmallCrates() { return true; } +bool Logic::CanBonkTrees() { + return true; +} + bool Logic::HasExplosives() { return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 1d0dee6bc..03be61296 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -95,6 +95,7 @@ class Logic { bool CanBreakPots(); bool CanBreakCrates(); bool CanBreakSmallCrates(); + bool CanBonkTrees(); bool HasFireSource(); bool HasFireSourceWithTorch(); bool TradeQuestStep(RandomizerGet rg); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index ce612001b..4a981fccb 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -290,6 +290,11 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle crates that are outside of dungeons.\n" "\n" "All Crates - Shuffle all crates."; + mOptionDescriptions[RSK_SHUFFLE_TREES] = + "Trees will contain randomized items which are dropped the first time the player rolls into one.\n" + "Trees will have a special appearance when carrying randomized items.\n" + "\nSome trees are dependant on Link's age, such as some trees in Hyrule Field.\nTwo trees at Hyrule Castle are " + "only shuffle with No Logic."; mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index ac0b7ea4a..345c27ab8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3332,6 +3332,69 @@ std::map rcToRandomizerInf = { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, }, + { RC_MARKET_TREE, RAND_INF_MARKET_TREE }, + { RC_HC_NEAR_GUARDS_TREE_1, RAND_INF_HC_NEAR_GUARDS_TREE_1 }, + { RC_HC_NEAR_GUARDS_TREE_2, RAND_INF_HC_NEAR_GUARDS_TREE_2 }, + { RC_HC_NEAR_GUARDS_TREE_3, RAND_INF_HC_NEAR_GUARDS_TREE_3 }, + { RC_HC_NEAR_GUARDS_TREE_4, RAND_INF_HC_NEAR_GUARDS_TREE_4 }, + { RC_HC_NEAR_GUARDS_TREE_5, RAND_INF_HC_NEAR_GUARDS_TREE_5 }, + { RC_HC_NEAR_GUARDS_TREE_6, RAND_INF_HC_NEAR_GUARDS_TREE_6 }, + { RC_HC_SKULLTULA_TREE, RAND_INF_HC_SKULLTULA_TREE }, + { RC_HC_GROTTO_TREE, RAND_INF_HC_GROTTO_TREE }, + { RC_HC_NL_TREE_1, RAND_INF_HC_NL_TREE_1 }, + { RC_HC_NL_TREE_2, RAND_INF_HC_NL_TREE_2 }, + { RC_HF_NEAR_KAK_TREE, RAND_INF_HF_NEAR_KAK_TREE }, + { RC_HF_NEAR_KAK_SMALL_TREE, RAND_INF_HF_NEAR_KAK_SMALL_TREE }, + { RC_HF_NEAR_MARKET_TREE_1, RAND_INF_HF_NEAR_MARKET_TREE_1 }, + { RC_HF_NEAR_MARKET_TREE_2, RAND_INF_HF_NEAR_MARKET_TREE_2 }, + { RC_HF_NEAR_MARKET_TREE_3, RAND_INF_HF_NEAR_MARKET_TREE_3 }, + { RC_HF_NEAR_LLR_TREE, RAND_INF_HF_NEAR_LLR_TREE }, + { RC_HF_NEAR_LH_TREE, RAND_INF_HF_NEAR_LH_TREE }, + { RC_HF_CHILD_NEAR_GV_TREE, RAND_INF_HF_CHILD_NEAR_GV_TREE }, + { RC_HF_ADULT_NEAR_GV_TREE, RAND_INF_HF_ADULT_NEAR_GV_TREE }, + { RC_HF_NEAR_ZR_TREE, RAND_INF_HF_NEAR_ZR_TREE }, + { RC_HF_NORTHWEST_TREE_1, RAND_INF_HF_NORTHWEST_TREE_1 }, + { RC_HF_NORTHWEST_TREE_2, RAND_INF_HF_NORTHWEST_TREE_2 }, + { RC_HF_NORTHWEST_TREE_3, RAND_INF_HF_NORTHWEST_TREE_3 }, + { RC_HF_NORTHWEST_TREE_4, RAND_INF_HF_NORTHWEST_TREE_4 }, + { RC_HF_NORTHWEST_TREE_5, RAND_INF_HF_NORTHWEST_TREE_5 }, + { RC_HF_NORTHWEST_TREE_6, RAND_INF_HF_NORTHWEST_TREE_6 }, + { RC_HF_EAST_TREE_1, RAND_INF_HF_EAST_TREE_1 }, + { RC_HF_EAST_TREE_2, RAND_INF_HF_EAST_TREE_2 }, + { RC_HF_EAST_TREE_3, RAND_INF_HF_EAST_TREE_3 }, + { RC_HF_EAST_TREE_4, RAND_INF_HF_EAST_TREE_4 }, + { RC_HF_EAST_TREE_5, RAND_INF_HF_EAST_TREE_5 }, + { RC_HF_EAST_TREE_6, RAND_INF_HF_EAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_1, RAND_INF_HF_SOUTHEAST_TREE_1 }, + { RC_HF_SOUTHEAST_TREE_2, RAND_INF_HF_SOUTHEAST_TREE_2 }, + { RC_HF_SOUTHEAST_TREE_3, RAND_INF_HF_SOUTHEAST_TREE_3 }, + { RC_HF_SOUTHEAST_TREE_4, RAND_INF_HF_SOUTHEAST_TREE_4 }, + { RC_HF_SOUTHEAST_TREE_5, RAND_INF_HF_SOUTHEAST_TREE_5 }, + { RC_HF_SOUTHEAST_TREE_6, RAND_INF_HF_SOUTHEAST_TREE_6 }, + { RC_HF_SOUTHEAST_TREE_7, RAND_INF_HF_SOUTHEAST_TREE_7 }, + { RC_HF_SOUTHEAST_TREE_8, RAND_INF_HF_SOUTHEAST_TREE_8 }, + { RC_HF_SOUTHEAST_TREE_9, RAND_INF_HF_SOUTHEAST_TREE_9 }, + { RC_HF_SOUTHEAST_TREE_10, RAND_INF_HF_SOUTHEAST_TREE_10 }, + { RC_HF_SOUTHEAST_TREE_11, RAND_INF_HF_SOUTHEAST_TREE_11 }, + { RC_HF_SOUTHEAST_TREE_12, RAND_INF_HF_SOUTHEAST_TREE_12 }, + { RC_HF_SOUTHEAST_TREE_13, RAND_INF_HF_SOUTHEAST_TREE_13 }, + { RC_HF_SOUTHEAST_TREE_14, RAND_INF_HF_SOUTHEAST_TREE_14 }, + { RC_HF_SOUTHEAST_TREE_15, RAND_INF_HF_SOUTHEAST_TREE_15 }, + { RC_HF_SOUTHEAST_TREE_16, RAND_INF_HF_SOUTHEAST_TREE_16 }, + { RC_HF_SOUTHEAST_TREE_17, RAND_INF_HF_SOUTHEAST_TREE_17 }, + { RC_HF_SOUTHEAST_TREE_18, RAND_INF_HF_SOUTHEAST_TREE_18 }, + { RC_HF_SOUTHEAST_TREE_19, RAND_INF_HF_SOUTHEAST_TREE_19 }, + { RC_HF_CHILD_SOUTHEAST_TREE_1, RAND_INF_HF_CHILD_SOUTHEAST_TREE_1 }, + { RC_HF_CHILD_SOUTHEAST_TREE_2, RAND_INF_HF_CHILD_SOUTHEAST_TREE_2 }, + { RC_HF_CHILD_SOUTHEAST_TREE_3, RAND_INF_HF_CHILD_SOUTHEAST_TREE_3 }, + { RC_HF_CHILD_SOUTHEAST_TREE_4, RAND_INF_HF_CHILD_SOUTHEAST_TREE_4 }, + { RC_HF_CHILD_SOUTHEAST_TREE_5, RAND_INF_HF_CHILD_SOUTHEAST_TREE_5 }, + { RC_HF_CHILD_SOUTHEAST_TREE_6, RAND_INF_HF_CHILD_SOUTHEAST_TREE_6 }, + { RC_HF_TEKTITE_GROTTO_TREE, RAND_INF_HF_TEKTITE_GROTTO_TREE }, + { RC_ZF_TREE, RAND_INF_ZF_TREE }, + { RC_ZR_TREE, RAND_INF_ZR_TREE }, + { RC_KAK_TREE, RAND_INF_KAK_TREE }, + { RC_LLR_TREE, RAND_INF_LLR_TREE }, }; BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -3753,6 +3816,27 @@ SmallCrateIdentity Randomizer::IdentifySmallCrate(s32 sceneNum, s32 posX, s32 po return smallCrateIdentity; } +TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { + struct TreeIdentity treeIdentity; + + if (sceneNum == SCENE_MARKET_NIGHT) { + sceneNum = SCENE_MARKET_DAY; + } + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_WOOD02, sceneNum, actorParams); + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK && + (location->GetRCType() != RCTYPE_NLTREE || GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) { + treeIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + treeIdentity.randomizerCheck = location->GetRandomizerCheck(); + return treeIdentity; + } + + treeIdentity.randomizerInf = RAND_INF_MAX; + treeIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + return treeIdentity; +} + u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 78f48b01c..54c85307b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -57,6 +57,7 @@ class Randomizer { GrassIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge); CrateIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); SmallCrateIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); + TreeIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9f105f400..92fe7348e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -416,6 +416,8 @@ typedef enum { RCTYPE_CRATE, // Crates RCTYPE_NLCRATE, // NL Crates RCTYPE_SMALL_CRATE, // Small crates + RCTYPE_TREE, // Trees + RCTYPE_NLTREE, // NL Trees RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives @@ -2750,6 +2752,72 @@ typedef enum { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, // End Crates + // Start Trees + RC_MARKET_TREE, + RC_HC_NEAR_GUARDS_TREE_1, + RC_HC_NEAR_GUARDS_TREE_2, + RC_HC_NEAR_GUARDS_TREE_3, + RC_HC_NEAR_GUARDS_TREE_4, + RC_HC_NEAR_GUARDS_TREE_5, + RC_HC_NEAR_GUARDS_TREE_6, + RC_HC_SKULLTULA_TREE, + RC_HC_GROTTO_TREE, + RC_HC_NL_TREE_1, + RC_HC_NL_TREE_2, + RC_HF_NEAR_LLR_TREE, + RC_HF_NEAR_LH_TREE, + RC_HF_CHILD_NEAR_GV_TREE, + RC_HF_ADULT_NEAR_GV_TREE, + RC_HF_NEAR_ZR_TREE, + RC_HF_NEAR_KAK_TREE, + RC_HF_NEAR_KAK_SMALL_TREE, + RC_HF_NEAR_MARKET_TREE_1, + RC_HF_NEAR_MARKET_TREE_2, + RC_HF_NEAR_MARKET_TREE_3, + RC_HF_NORTHWEST_TREE_1, + RC_HF_NORTHWEST_TREE_2, + RC_HF_NORTHWEST_TREE_3, + RC_HF_NORTHWEST_TREE_4, + RC_HF_NORTHWEST_TREE_5, + RC_HF_NORTHWEST_TREE_6, + RC_HF_EAST_TREE_1, + RC_HF_EAST_TREE_2, + RC_HF_EAST_TREE_3, + RC_HF_EAST_TREE_4, + RC_HF_EAST_TREE_5, + RC_HF_EAST_TREE_6, + RC_HF_SOUTHEAST_TREE_1, + RC_HF_SOUTHEAST_TREE_2, + RC_HF_SOUTHEAST_TREE_3, + RC_HF_SOUTHEAST_TREE_4, + RC_HF_SOUTHEAST_TREE_5, + RC_HF_SOUTHEAST_TREE_6, + RC_HF_SOUTHEAST_TREE_7, + RC_HF_SOUTHEAST_TREE_8, + RC_HF_SOUTHEAST_TREE_9, + RC_HF_SOUTHEAST_TREE_10, + RC_HF_SOUTHEAST_TREE_11, + RC_HF_SOUTHEAST_TREE_12, + RC_HF_SOUTHEAST_TREE_13, + RC_HF_SOUTHEAST_TREE_14, + RC_HF_SOUTHEAST_TREE_15, + RC_HF_SOUTHEAST_TREE_16, + RC_HF_SOUTHEAST_TREE_17, + RC_HF_SOUTHEAST_TREE_18, + RC_HF_SOUTHEAST_TREE_19, + RC_HF_CHILD_SOUTHEAST_TREE_1, + RC_HF_CHILD_SOUTHEAST_TREE_2, + RC_HF_CHILD_SOUTHEAST_TREE_3, + RC_HF_CHILD_SOUTHEAST_TREE_4, + RC_HF_CHILD_SOUTHEAST_TREE_5, + RC_HF_CHILD_SOUTHEAST_TREE_6, + RC_HF_TEKTITE_GROTTO_TREE, + RC_ZF_TREE, + RC_ZR_TREE, + RC_KAK_TREE, + RC_LLR_TREE, + // End Trees + RC_PIERRE, RC_DELIVER_RUTOS_LETTER, RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, @@ -5589,6 +5657,14 @@ typedef enum { RHT_CRATE_SPIRIT_TEMPLE, RHT_CRATE_SHADOW_TEMPLE, RHT_CRATE_GERUDO_TRAINING_GROUND, + // Shuffle Trees + RHT_TREE_HYRULE_FIELD, + RHT_TREE_MARKET, + RHT_TREE_HYRULE_CASTLE, + RHT_TREE_ZORAS_FOUNTAIN, + RHT_TREE_ZORAS_RIVER, + RHT_TREE_LON_LON_RANCH, + RHT_TREE_KAKARIKO, // Ganon Line RHT_GANON_JOKE01, RHT_GANON_JOKE02, @@ -5928,6 +6004,7 @@ typedef enum { RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, RSK_SHUFFLE_POTS, RSK_SHUFFLE_CRATES, + RSK_SHUFFLE_TREES, RSK_SHUFFLE_FROG_SONG_RUPEES, RSK_ITEM_POOL, RSK_ICE_TRAPS, @@ -6547,6 +6624,11 @@ typedef struct SmallCrateIdentity { RandomizerCheck randomizerCheck; } SmallCrateIdentity; +typedef struct TreeIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} TreeIdentity; + typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index da05ee508..f8a73ddd2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -189,6 +189,10 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_SMALL_CRATE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_TREE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_NLTREE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTrees"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index ee1a8d9c0..aab671088 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -81,6 +81,7 @@ bool showOverworldGrass; bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; +bool showTrees; bool showFrogSongRupees; bool showFairies; bool showStartingMapsCompasses; @@ -1469,6 +1470,7 @@ void LoadSettings() { showDungeonCrates = false; break; } + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; @@ -1478,6 +1480,7 @@ void LoadSettings() { showDungeonGrass = false; showOverworldCrates = false; showDungeonCrates = false; + showTrees = false; } fortressFast = false; @@ -1554,9 +1557,9 @@ bool IsCheckShuffled(RandomizerCheck rc) { return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them (loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them - (loc->GetRCType() != - RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them - (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it + (loc->GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we + // support shuffling them + (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it (rc != RC_LINKS_POCKET || showLinksPocket) && OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && (loc->GetRCType() != RCTYPE_SHOP || @@ -1590,6 +1593,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_SMALL_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_TREE || showTrees) && + (loc->GetRCType() != RCTYPE_NLTREE || + (showTrees && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index d42e14cb1..8742805a6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -997,6 +997,69 @@ DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3) DEFINE_RAND_INF(RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4) DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE) DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE) +DEFINE_RAND_INF(RAND_INF_MARKET_TREE) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_1) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_2) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_3) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_4) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_5) +DEFINE_RAND_INF(RAND_INF_HC_NEAR_GUARDS_TREE_6) +DEFINE_RAND_INF(RAND_INF_HC_SKULLTULA_TREE) +DEFINE_RAND_INF(RAND_INF_HC_GROTTO_TREE) +DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_1) +DEFINE_RAND_INF(RAND_INF_HC_NL_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_LLR_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_LH_TREE) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NEAR_GV_TREE) +DEFINE_RAND_INF(RAND_INF_HF_ADULT_NEAR_GV_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_ZR_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_KAK_SMALL_TREE) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NEAR_MARKET_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_NORTHWEST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_EAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_7) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_8) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_9) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_10) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_11) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_12) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_13) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_14) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_15) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_16) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_17) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_18) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHEAST_TREE_19) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6) +DEFINE_RAND_INF(RAND_INF_HF_TEKTITE_GROTTO_TREE) +DEFINE_RAND_INF(RAND_INF_ZF_TREE) +DEFINE_RAND_INF(RAND_INF_ZR_TREE) +DEFINE_RAND_INF(RAND_INF_KAK_TREE) +DEFINE_RAND_INF(RAND_INF_LLR_TREE) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index fc1e95d49..bb3365304 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -217,6 +217,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); + OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES, "Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); @@ -1287,6 +1288,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -1538,6 +1540,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 7bdec17c1..d6a151391 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -58,6 +58,7 @@ class StaticData { static void RegisterFreestandingLocations(); static void RegisterGrassLocations(); static void RegisterCrateLocations(); + static void RegisterTreeLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index 2fe2445a6..1fe96d38c 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -357,16 +357,18 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) { dropsSpawnPt = this->actor.world.pos; dropsSpawnPt.y += 200.0f; - if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { - if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) { - Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); + if (GameInteractor_Should(VB_TREE_DROP_ITEM, true, this)) { + if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { + if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) { + Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); + } + } else if (this->actor.home.rot.z != 0) { + this->actor.home.rot.z &= 0x1FFF; + this->actor.home.rot.z |= 0xE000; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0, + this->actor.world.rot.y, 0, this->actor.home.rot.z, true); + this->actor.home.rot.z = 0; } - } else if (this->actor.home.rot.z != 0) { - this->actor.home.rot.z &= 0x1FFF; - this->actor.home.rot.z |= 0xE000; - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, dropsSpawnPt.z, 0, - this->actor.world.rot.y, 0, this->actor.home.rot.z, true); - this->actor.home.rot.z = 0; } // Spawn falling leaves @@ -457,12 +459,13 @@ void EnWood02_Draw(Actor* thisx, PlayState* play) { } Gfx_SetupDL_25Xlu(gfxCtx); - - if ((this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW)) { + if (GameInteractor_Should(VB_TREE_SETUP_DRAW, + (this->actor.params == WOOD_LEAF_GREEN) || (this->actor.params == WOOD_LEAF_YELLOW), + this)) { Gfx_SetupDL_25Opa(gfxCtx); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127); Gfx_DrawDListOpa(play, object_wood02_DL_000700); - } else if (D_80B3BF70[this->drawType & 0xF] != NULL) { + } else if (GameInteractor_Should(VB_TREE_SETUP_DRAW, D_80B3BF70[this->drawType & 0xF] != NULL, this)) { Gfx_DrawDListOpa(play, D_80B3BF54[this->drawType & 0xF]); gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); From 5cac826f97525a7de8b2d7ef8913d560ca50183e Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 3 Oct 2025 00:45:58 +0200 Subject: [PATCH 78/98] Add a warning for disabled network (#5629) * Update SohMenu.cpp * clang * Prevent warning from appearing in release builds --- soh/soh/SohGui/SohMenu.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/soh/soh/SohGui/SohMenu.cpp b/soh/soh/SohGui/SohMenu.cpp index d5c2c0c1f..547025391 100644 --- a/soh/soh/SohGui/SohMenu.cpp +++ b/soh/soh/SohGui/SohMenu.cpp @@ -81,14 +81,33 @@ SohMenu::SohMenu(const std::string& consoleVariable, const std::string& name) : Menu(consoleVariable, name, 0, UIWidgets::Colors::LightBlue) { } +#ifndef ENABLE_REMOTE_CONTROL +void SohMenu::AddMenuNetwork() { +#ifndef _DEBUG + // in release builds, the tab doesn't even show + return; +#endif + + // Add Network Menu + AddMenuEntry("Network", CVAR_SETTING("Menu.NetworkSidebarSection")); + + WidgetPath path = { "Network", "Info", SECTION_COLUMN_1 }; + AddSidebarEntry("Network", path.sidebarName, 2); + + AddWidget(path, + ICON_FA_EXCLAMATION_TRIANGLE " The Network features are unavailable because SoH was compiled without " + "network support (\"ENABLE_REMOTE_CONTROL\" build flag).", + WIDGET_TEXT) + .Options(TextOptions().Color(Colors::Orange)); +} +#endif + void SohMenu::InitElement() { Ship::Menu::InitElement(); AddMenuSettings(); AddMenuEnhancements(); AddMenuRandomizer(); -#ifdef ENABLE_REMOTE_CONTROL AddMenuNetwork(); -#endif AddMenuDevTools(); if (CVarGetInteger(CVAR_SETTING("Menu.SidebarSearch"), 0)) { From c22fbc08d70aae7d7fdd54e3029b5bb403bad944 Mon Sep 17 00:00:00 2001 From: Nivomi Date: Thu, 2 Oct 2025 18:47:48 -0400 Subject: [PATCH 79/98] Fix "SpawnActor::CanBeApplied" check which would also actually spawn the actor, thus causing two actors two be spawned (also fix for WithOffset) (#5822) --- .../game-interactor/GameInteractionEffect.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 76e026206..682a1271e 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -632,10 +632,10 @@ void SlipperyFloor::_Remove() { // MARK: - SpawnEnemyWithOffset GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded(true)) { + if (!GameInteractor::CanSpawnActor()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } - return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); + return GameInteractionEffectQueryResult::Possible; } void SpawnEnemyWithOffset::_Apply() { @@ -644,10 +644,10 @@ void SpawnEnemyWithOffset::_Apply() { // MARK: - SpawnActor GameInteractionEffectQueryResult SpawnActor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded(true)) { + if (!GameInteractor::CanSpawnActor()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } - return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); + return GameInteractionEffectQueryResult::Possible; } void SpawnActor::_Apply() { From 004890f2f8b54791cc15617541138635fc1a558e Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Fri, 3 Oct 2025 02:06:58 +0200 Subject: [PATCH 80/98] French Translation - Treesanity (#5827) * French Translation * French Translation --- .../hint_list/hint_list_exclude_overworld.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 2fe5992bf..0c40dfdb9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2105,27 +2105,27 @@ void StaticData::HintTable_Init_Exclude_Overworld() { hintTextTable[RHT_TREE_HYRULE_FIELD] = HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre dans la Plaine d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_TREE_MARKET] = HintText(CustomMessage("They say that a #tree in Hyrule Market# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre sur la Place du Marché# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_TREE_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #tree in Hyrule Castle# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre au Château d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_TREE_ZORAS_RIVER] = HintText(CustomMessage("They say that a #tree in Zora's River# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre à la Rivière Zora# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_TREE_ZORAS_FOUNTAIN] = HintText(CustomMessage("They say that a #tree in Zora's Fountain# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre à la Fontaine Zora# cache #[[1]]#.", { QM_RED, QM_GREEN })); hintTextTable[RHT_TREE_LON_LON_RANCH] = HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", /*german*/ "", - /*french*/ "", { QM_RED, QM_GREEN })); + /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); // clang-format on } } // namespace Rando From 6c724382f5171113cf051ace271c48726fc2a279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 5 Oct 2025 01:54:53 +0000 Subject: [PATCH 81/98] rando: fix reentry of jabu blue warp (#5829) * rando: fix reentry of jabu blue warp entrance randomizer uses VB_PLAY_BLUE_WARP_CS to set a flag, which was not called when entering jabu blue warp without ruto * alternative --- .../TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index 83e459fab..29b56e87b 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -168,8 +168,9 @@ void RegisterShouldPlayBlueWarp() { } // This is outside the above condition because we want to handle both first and following visits to the blue - // warp - if (sEnteredBlueWarp && overrideBlueWarpDestinations) { + // warp. Jabu's blue warp doesn't call VB_PLAY_BLUE_WARP_CS without Ruto + if ((sEnteredBlueWarp || gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP) && + overrideBlueWarpDestinations) { Entrance_OverrideBlueWarp(); } } From dd2628f737d12f32accc030c44d1572ecd97d12c Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya0@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:57:01 -0400 Subject: [PATCH 82/98] sequence notifs (updated #5265) (#5824) * Adds ability for Notifiations to not make a noise This is probably the only feature that will use it, the noise makes sense for most things we want to use notifications for, but it playing on every scene transition was a bit distracting. * Adds a hook for OnSeqPlayerInit * Uses new hook and displays notification instead of overlay text * Changes names to prevent collisions Will be registering other types of hooks that will need different ShipInitFuncs in this same file later. * Change Icon * Change CVarName and remove now-unused duration slider * Update ConfigMigrator for CVar changes. * clang-format * fix * bring back duration control * config v4 * fix v4 migration --------- Co-authored-by: Christopher Leggett Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> --- soh/soh/Enhancements/audio/AudioEditor.cpp | 15 +++---- soh/soh/Enhancements/audio/AudioHooks.cpp | 43 +++++++++++++++++++ .../GameInteractor_HookTable.h | 3 ++ .../game-interactor/GameInteractor_Hooks.cpp | 5 +++ .../game-interactor/GameInteractor_Hooks.h | 3 ++ soh/soh/Notification/Notification.cpp | 6 ++- soh/soh/Notification/Notification.h | 1 + soh/soh/OTRGlobals.cpp | 1 + soh/soh/config/ConfigMigrators.h | 5 +++ soh/soh/config/ConfigUpdaters.cpp | 11 +++++ soh/soh/config/ConfigUpdaters.h | 6 +++ soh/src/code/audio_load.c | 15 +------ 12 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 soh/soh/Enhancements/audio/AudioHooks.cpp diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 18b5cec1a..c64ed7b42 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -842,18 +842,17 @@ void RegisterAudioWidgets() { "the area for the effect to kick in.")); SohGui::mSohMenu->AddSearchWidget({ leadingMusic, "Enhancements", "Audio Editor", "Audio Options" }); - displaySeqName = { .name = "Display Sequence Name on Overlay", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; - displaySeqName.CVar(CVAR_AUDIO("SeqNameOverlay")) + displaySeqName = { .name = "Display Sequence Name in Notifications", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; + displaySeqName.CVar(CVAR_AUDIO("SeqNameNotification")) .Options(CheckboxOptions() .Color(THEME_COLOR) - .Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new " - "sequence " - "is loaded to the main sequence player (does not apply to fanfares or enemy BGM).")); + .Tooltip("Emits a notification with the current song name whenever it changes. " + "(does not apply to fanfares or enemy BGM).")); SohGui::mSohMenu->AddSearchWidget({ displaySeqName, "Enhancements", "Audio Editor", "Audio Options" }); - ovlDuration = { .name = "Overlay Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT }; - ovlDuration.CVar(CVAR_AUDIO("SeqNameOverlayDuration")) - .Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(10).DefaultValue(5).Size(ImVec2(300.0f, 0.0f))); + ovlDuration = { .name = "Sequence Notification Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT }; + ovlDuration.CVar(CVAR_AUDIO("SeqNameNotificationDuration")) + .Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(20).DefaultValue(10).Size(ImVec2(300.0f, 0.0f))); SohGui::mSohMenu->AddSearchWidget({ ovlDuration, "Enhancements", "Audio Editor", "Audio Options" }); voicePitch = { .name = "Link's Voice Pitch Multiplier", .type = WidgetType::WIDGET_CVAR_SLIDER_FLOAT }; diff --git a/soh/soh/Enhancements/audio/AudioHooks.cpp b/soh/soh/Enhancements/audio/AudioHooks.cpp new file mode 100644 index 000000000..d2d6aa279 --- /dev/null +++ b/soh/soh/Enhancements/audio/AudioHooks.cpp @@ -0,0 +1,43 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include "AudioCollection.h" +#include +#include + +extern "C" { +#include "variables.h" + +extern PlayState* gPlayState; +} + +#define CVAR_SEQOVERLAY_NAME CVAR_AUDIO("SeqNameNotification") +#define CVAR_SEQOVERLAY_DEFAULT 0 +#define CVAR_SEQOVERLAY_VALUE CVarGetInteger(CVAR_SEQOVERLAY_NAME, CVAR_SEQOVERLAY_DEFAULT) + +void NotifySequenceName(int32_t playerIdx, int32_t seqId) { + // Keep track of the previous sequence/scene so we don't repeat notifications + static uint16_t previousSeqId = UINT16_MAX; + static int16_t previousSceneNum = INT16_MAX; + if (playerIdx == SEQ_PLAYER_BGM_MAIN && + (seqId != previousSeqId || (gPlayState != NULL && gPlayState->sceneNum != previousSceneNum))) { + + previousSeqId = seqId; + if (gPlayState != NULL) { + previousSceneNum = gPlayState->sceneNum; + } + const char* sequenceName = AudioCollection::Instance->GetSequenceName(seqId); + if (sequenceName != NULL) { + Notification::Emit({ + .message = ICON_FA_MUSIC " " + std::string(sequenceName), + .remainingTime = static_cast(CVarGetInteger(CVAR_AUDIO("SeqNameNotificationDuration"), 10)), + .mute = true, + }); + } + } +} + +void RegisterAudioNotificationHooks() { + COND_HOOK(OnSeqPlayerInit, CVAR_SEQOVERLAY_VALUE, NotifySequenceName); +} + +static RegisterShipInitFunc notifInitFunc(RegisterAudioNotificationHooks, { CVAR_SEQOVERLAY_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index b5b1cfbfe..0f694660c 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -74,3 +74,6 @@ DEFINE_HOOK(OnGenerationCompletion, ()); DEFINE_HOOK(OnSetGameLanguage, ()); DEFINE_HOOK(OnAssetAltChange, ()); DEFINE_HOOK(OnKaleidoUpdate, ()); + +// Audio +DEFINE_HOOK(OnSeqPlayerInit, (int32_t playerIdx, int32_t seqId)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index f374aa2d7..7d5a243d2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -327,3 +327,8 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) { void GameInteractor_ExecuteOnKaleidoUpdate() { GameInteractor::Instance->ExecuteHooks(); } + +// Mark: Audio +void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId) { + GameInteractor::Instance->ExecuteHooks(playerIdx, seqId); +} diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index e22d12dbd..4c3a600e7 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -86,6 +86,9 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)); // Mark: - Pause Menu void GameInteractor_ExecuteOnKaleidoUpdate(); +// Mark: - Audio +void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId); + #ifdef __cplusplus } #endif diff --git a/soh/soh/Notification/Notification.cpp b/soh/soh/Notification/Notification.cpp index 14873b068..c70841960 100644 --- a/soh/soh/Notification/Notification.cpp +++ b/soh/soh/Notification/Notification.cpp @@ -131,8 +131,10 @@ void Emit(Options notification) { notification.remainingTime = CVarGetFloat(CVAR_SETTING("Notifications.Duration"), 10.0f); } notifications.push_back(notification); - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + if (!notification.mute) { + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } } } // namespace Notification diff --git a/soh/soh/Notification/Notification.h b/soh/soh/Notification/Notification.h index 7eb4bb2d7..bf1d4ec04 100644 --- a/soh/soh/Notification/Notification.h +++ b/soh/soh/Notification/Notification.h @@ -17,6 +17,7 @@ struct Options { std::string suffix = ""; ImVec4 suffixColor = ImVec4(1.0f, 0.5f, 0.5f, 1.0f); float remainingTime = 0.0f; // Seconds + bool mute = false; // whether notification should make a noise }; class Window final : public Ship::GuiWindow { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 963a5b00d..a0ffdc1d1 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1237,6 +1237,7 @@ extern "C" void InitOTR() { conf->RegisterVersionUpdater(std::make_shared()); conf->RegisterVersionUpdater(std::make_shared()); conf->RegisterVersionUpdater(std::make_shared()); + conf->RegisterVersionUpdater(std::make_shared()); conf->RunVersionUpdates(); SohGui::SetupGuiElements(); diff --git a/soh/soh/config/ConfigMigrators.h b/soh/soh/config/ConfigMigrators.h index ee7e91792..54a0dc236 100644 --- a/soh/soh/config/ConfigMigrators.h +++ b/soh/soh/config/ConfigMigrators.h @@ -1520,4 +1520,9 @@ std::vector version3Migrations = { { MigrationAction::Remove, "gPreset0" }, { MigrationAction::Remove, "gPreset1" }, }; + +std::vector version4Migrations = { + { MigrationAction::Rename, "gAudioEditor.SeqNameOverlay", "gAudioEditor.SeqNameNotification" }, + { MigrationAction::Rename, "gAudioEditor.SeqNameOverlayDuration", "gAudioEditor.SeqNameNotificationDuration" }, +}; } // namespace SOH diff --git a/soh/soh/config/ConfigUpdaters.cpp b/soh/soh/config/ConfigUpdaters.cpp index ff451d98c..a7c50a845 100644 --- a/soh/soh/config/ConfigUpdaters.cpp +++ b/soh/soh/config/ConfigUpdaters.cpp @@ -9,6 +9,8 @@ ConfigVersion2Updater::ConfigVersion2Updater() : ConfigVersionUpdater(2) { } ConfigVersion3Updater::ConfigVersion3Updater() : ConfigVersionUpdater(3) { } +ConfigVersion4Updater::ConfigVersion4Updater() : ConfigVersionUpdater(4) { +} void ConfigVersion1Updater::Update(Ship::Config* conf) { if (conf->GetInt("Window.Width", 640) == 640) { @@ -111,4 +113,13 @@ void ConfigVersion3Updater::Update(Ship::Config* conf) { CVarClear(migration.from.c_str()); } } + +void ConfigVersion4Updater::Update(Ship::Config* conf) { + for (Migration migration : version4Migrations) { + if (migration.action == MigrationAction::Rename) { + CVarCopy(migration.from.c_str(), migration.to.value().c_str()); + } + CVarClear(migration.from.c_str()); + } +} } // namespace SOH diff --git a/soh/soh/config/ConfigUpdaters.h b/soh/soh/config/ConfigUpdaters.h index 7912be7de..948188c19 100644 --- a/soh/soh/config/ConfigUpdaters.h +++ b/soh/soh/config/ConfigUpdaters.h @@ -18,4 +18,10 @@ class ConfigVersion3Updater final : public Ship::ConfigVersionUpdater { ConfigVersion3Updater(); void Update(Ship::Config* conf); }; + +class ConfigVersion4Updater final : public Ship::ConfigVersionUpdater { + public: + ConfigVersion4Updater(); + void Update(Ship::Config* conf); +}; } // namespace SOH diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index 52efa4016..f5d24756d 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -8,6 +8,7 @@ #include "soh/Enhancements/audio/AudioCollection.h" #include "soh/Enhancements/audio/AudioEditor.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #ifdef _MSC_VER #define strdup _strdup @@ -630,19 +631,7 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { AudioSeq_SkipForwardSequence(seqPlayer); //! @bug missing return (but the return value is not used so it's not UB) - // Keep track of the previous sequence/scene so we don't repeat notifications - static uint16_t previousSeqId = UINT16_MAX; - static int16_t previousSceneNum = INT16_MAX; - if (CVarGetInteger(CVAR_AUDIO("SeqNameOverlay"), 0) && playerIdx == SEQ_PLAYER_BGM_MAIN && - (seqId != previousSeqId || (gPlayState != NULL && gPlayState->sceneNum != previousSceneNum))) { - - previousSeqId = seqId; - if (gPlayState != NULL) { - previousSceneNum = gPlayState->sceneNum; - } - - AudioCollection_EmitSongNameNotification(seqId); - } + GameInteractor_ExecuteOnSeqPlayerInit(playerIdx, seqId); } u8* AudioLoad_SyncLoadSeq(s32 seqId) { From b337f3873763e845f4412e5ae35502101b0dad48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 5 Oct 2025 18:04:38 +0000 Subject: [PATCH 83/98] Add a RT_GF_JUMP case (#5828) Adult can make jump without hover boots by jumping beside the wall (oddly, to the higher part of slope) Only matters with Shuffle Climb --- .../randomizer/location_access/overworld/gerudo_fortress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index b37c4f08e..4e29f7e6d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -132,7 +132,7 @@ void RegionTable_Init_GerudoFortress() { //Exits Entrance(RR_GF_OUTSIDE_GTG, []{return true;}), Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}), - Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_JUMP));}), Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}), Entrance(RR_GF_TO_GTG, []{return logic->IsAdult && ctx->GetTrickOption(RT_GF_LEDGE_CLIP_INTO_GTG).Get();}), }); From f4336cdec7b89571be05d50784757ebf4597f2b2 Mon Sep 17 00:00:00 2001 From: aMannus Date: Mon, 6 Oct 2025 03:02:13 +0200 Subject: [PATCH 84/98] Add fairy event to outside deku tree (#5830) --- .../randomizer/location_access/overworld/kokiri_forest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 09e5a6d4a..8c548745a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -93,6 +93,7 @@ void RegionTable_Init_KokiriForest() { //Events EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}), EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), + EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), }, { //Locations From 5e199ffea8c291b686156570e6498e2aa4595443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 6 Oct 2025 01:24:32 +0000 Subject: [PATCH 85/98] RT_HOOKSHOT_EXTENSION (#5704) * 2 hookshot extension tricks * consolidation * not a glitch * cleanup spirit logic * clang --- .../location_access/dungeons/ganons_castle.cpp | 12 ++++++------ .../location_access/dungeons/spirit_temple.cpp | 3 ++- .../overworld/death_mountain_trail.cpp | 2 +- .../location_access/overworld/gerudo_valley.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 +- soh/soh/Enhancements/randomizer/settings.cpp | 11 +++++++---- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index de95e359f..6a8ce96fc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -104,14 +104,14 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(LOGIC_NUT_POT, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), - EventAccess(LOGIC_SPIRIT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), + EventAccess(LOGIC_NUT_POT, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), + EventAccess(LOGIC_SPIRIT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_BOMBCHU_5))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), }, {}); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 8b75e7b95..207b9c76f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -133,7 +133,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", SCENE_SPIRIT_TEMPLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && (logic->CanJumpslash() || logic->HasExplosives() || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOOKSHOT))))) || + (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index dc86bd97e..42fa22cf9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -14,7 +14,7 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()), - LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()), + LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 0e6fe7412..f613e969a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -17,7 +17,7 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_GROTTO_LEDGE, []{return true;}), - Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || ((logic->IsChild || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild;}), //can use cucco as child }); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 92fe7348e..4469e909c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3704,6 +3704,7 @@ typedef enum { RT_BOMBCHU_BEEHIVES, RT_BLUE_FIRE_MUD_WALLS, RT_OPEN_UNDERWATER_CHEST, + RT_HOOKSHOT_EXTENSION, RT_KF_ADULT_GS, // -- location tricks RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, @@ -3720,7 +3721,6 @@ typedef enum { RT_GY_SHADOW_FIRE_ARROWS, RT_DMT_SOIL_GS, RT_DMT_BOMBABLE, - RT_DMT_HOOKSHOT_LOWER_GS, RT_DMT_HOVERS_LOWER_GS, RT_DMT_BEAN_LOWER_GS, RT_DMT_JS_LOWER_GS, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index bb3365304..818ac5ebf 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -410,6 +410,13 @@ void Settings::CreateOptions() { OPT_TRICK(RT_OPEN_UNDERWATER_CHEST, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Open Underwater Chests", "Underwater chests can be opened by wearing iron boots and hookshotting the chest."); + OPT_TRICK(RT_HOOKSHOT_EXTENSION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, + "Hookshot/Projectile Extension", + "Slightly extends range. Also allows clipping projectile past collision. Used for:\n" + "- Crossing Gerudo Valley with Hookshot\n" + "- Retrieving DMT Gold Skulltula beside bomb flower\n" + "- Hitting switch through wall in Spirit Temple's big mirror room with Bow, Slingshot, or Hookshot\n" + "- Hitting switch through wall in Spirit Trial with Bow or Slingshot"); OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, { Tricks::Tag::NOVICE }, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); @@ -475,10 +482,6 @@ void Settings::CreateOptions() { "Death Mountain Trail Chest with Strength", "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then " "quickly throw it toward the wall."); - OPT_TRICK(RT_DMT_HOOKSHOT_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, - "Death Mountain Trail Lower Red Rock GS with Hookshot", - "After killing the Skulltula, the token can be fished out of the rock without needing to destroy it, by " - "using the Hookshot in the correct way."); OPT_TRICK(RT_DMT_HOVERS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, "Death Mountain Trail Lower Red Rock GS with Hover Boots", "After killing the Skulltula, the token can be collected without needing to destroy the rock by " From 04780de5ecb1e146ec99c72260f6f230ee6311df Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 6 Oct 2025 17:03:38 -0700 Subject: [PATCH 86/98] Pulls in the Mac Prism fix. (#5832) --- libultraship | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship b/libultraship index 64f16273a..d1bbd53e8 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 64f16273a37075bd5d2b5ee6291848370ea7b822 +Subproject commit d1bbd53e8a1d2a4d6cfcce588ed13aa8d0686909 From 474d944cfa8125aaa2e3734ff4d14937c804ac25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 7 Oct 2025 04:33:59 +0000 Subject: [PATCH 87/98] RT_GROUND_JUMP (#5745) * RT_GROUND_JUMP, RT_GROUND_JUMP_HARD based on zootr logic * 2 groundjumps in Gerudo Fortress --- .../location_access/dungeons/deku_tree.cpp | 4 ++-- .../location_access/dungeons/dodongos_cavern.cpp | 12 ++++++------ .../location_access/dungeons/fire_temple.cpp | 6 +++--- .../location_access/dungeons/forest_temple.cpp | 2 +- .../location_access/dungeons/ganons_castle.cpp | 10 +++++----- .../dungeons/gerudo_training_ground.cpp | 6 +++--- .../location_access/dungeons/ice_cavern.cpp | 14 +++++++------- .../location_access/dungeons/shadow_temple.cpp | 6 +++--- .../location_access/overworld/gerudo_fortress.cpp | 3 ++- .../location_access/overworld/graveyard.cpp | 2 +- .../overworld/haunted_wasteland.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 5 +++++ soh/soh/Enhancements/randomizer/logic.h | 1 + soh/soh/Enhancements/randomizer/randomizerTypes.h | 1 + soh/soh/Enhancements/randomizer/settings.cpp | 11 ++++++++--- 15 files changed, 49 insertions(+), 36 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 7de1c43f8..caa46d9c7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -91,7 +91,7 @@ void RegionTable_Init_DekuTree() { //Exits Entrance(RR_DEKU_TREE_LOBBY, []{return true;}), Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}), - Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK);}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->CanGroundJump() || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK);}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}), }); @@ -309,7 +309,7 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();});}), //includes RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM Access, other fire sources clear directly from there Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM) && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}), - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->CanGroundJump() || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) || logic->CanUse(RG_HOVER_BOOTS);}), }); areaTable[RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM] = Region("Deku Tree MQ Southeast Room", SCENE_DEKU_TREE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 1bb3cb1ed..c21a7a33e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -35,7 +35,7 @@ void RegionTable_Init_DodongosCavern() { }, { //Exits Entrance(RR_DODONGOS_CAVERN_BEGINNING, []{return true;}), - Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, []{return logic->IsAdult;}), + Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, []{return logic->IsAdult || logic->CanGroundJump(true);}), Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->Get(LOGIC_DC_STAIRS_ROOM_DOOR);}), Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->Get(LOGIC_DC_LIFT_PLATFORM);}), @@ -169,7 +169,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return true;}), Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}), Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}), - Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, []{return (logic->IsAdult && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, []{return (logic->IsAdult && (ctx->GetTrickOption(RT_DC_JUMP) || logic->CanGroundJump())) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}), }); areaTable[RR_DODONGOS_CAVERN_2F_SIDE_ROOM] = Region("Dodongos Cavern 2F Side Room", SCENE_DODONGOS_CAVERN, {}, { @@ -189,7 +189,7 @@ void RegionTable_Init_DodongosCavern() { }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return true;}), - Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}), + Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP) || (logic->IsAdult && logic->CanGroundJump());}), }); areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", SCENE_DODONGOS_CAVERN, {}, { @@ -294,9 +294,8 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->HasItem(RG_GORONS_BRACELET) && logic->TakeDamage();});}), //strength 1 and bunny speed works too - Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->IsAdult;}), + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->IsAdult || logic->CanGroundJump(true);}), Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return logic->Get(LOGIC_DC_EYES_LIT);}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return Here(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}), }); areaTable[RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE] = Region("Dodongos Cavern MQ Gossip Stone", SCENE_DODONGOS_CAVERN, { @@ -406,7 +405,8 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return true;}), Entrance(RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM, []{return logic->HasFireSourceWithTorch();}),//torch checks here need strength 0 with sticks when that is implemented Entrance(RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, []{return Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, []{return logic->HasFireSourceWithTorch();});}), //Includes an implied CanPass(RE_BIG_SKULLTULA) - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return ((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), + //Bunny hood jump can make it as child + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return (logic->IsAdult && (ctx->GetTrickOption(RT_DC_JUMP) || logic->CanGroundJump())) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanUse(RG_STICKS) && logic->HasItem(RG_GORONS_BRACELET);}), //Implies access to RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM from here }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 2ccd8e6f1..d7ae81645 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -58,7 +58,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Region("Fire Temple Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && logic->IsAdult), + LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->IsAdult || logic->CanGroundJump())), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return true;}), @@ -144,7 +144,7 @@ void RegionTable_Init_FireTemple() { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH) || logic->CanGroundJump()) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {}, { @@ -255,7 +255,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return true;}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump();}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return ctx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index b3aa0abc7..a4a0563cf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -87,7 +87,7 @@ void RegionTable_Init_ForestTemple() { }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->CanUse(RG_SONG_OF_TIME);}), - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump()));}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return true;}), Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 6a8ce96fc..3f52a231c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -118,7 +118,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(LOGIC_LIGHT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), + EventAccess(LOGIC_LIGHT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), }, { //Locations LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), @@ -130,8 +130,8 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 1)), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), }, {}); #pragma endregion @@ -394,7 +394,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT] = Region("Ganon's Castle MQ Light Trial Boulder Room Front", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { //Exits Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_TRIFORCE_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2);}), - Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL) || logic->CanGroundJump();}), }); areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK] = Region("Ganon's Castle MQ Light Trial Boulder Room Back", SCENE_INSIDE_GANONS_CASTLE, {}, { @@ -404,7 +404,7 @@ void RegionTable_Init_GanonsCastle() { }, { //Exits //I got the trick going backwards, but only while taking damage. this isn't relevant anyway though - Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, []{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL) || logic->CanGroundJump();}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, []{return logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index c3f5b3f10..6d75dffb6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -96,8 +96,8 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true)), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}), - Entrance(RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_SILVER_GAUNTLETS);}), + Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump()));}), + Entrance(RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump())) && logic->CanUse(RG_SILVER_GAUNTLETS);}), }); areaTable[RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM] = Region("Gerudo Training Ground Like Like Room", SCENE_GERUDO_TRAINING_GROUND, {}, { @@ -186,7 +186,7 @@ void RegionTable_Init_GerudoTrainingGround() { }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && logic->CanUse(RG_SILVER_GAUNTLETS);}), - Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return logic->IsAdult && Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return logic->IsAdult && Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && logic->IsAdult && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump());}), }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK] = Region("Gerudo Training Ground MQ Behind Block", SCENE_GERUDO_TRAINING_GROUND, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 9aaaf27a5..823ff2eca 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -27,10 +27,10 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MAIN] = Region("Ice Cavern", SCENE_ICE_CAVERN, { //Events - EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsAdult;}), + EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump());}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && (logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump()))), LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS)), LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult), @@ -45,11 +45,11 @@ void RegionTable_Init_IceCavern() { LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire() && (logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump()))), LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, logic->IsAdult), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, logic->IsAdult), - LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), @@ -86,7 +86,7 @@ void RegionTable_Init_IceCavern() { //if you clear the ice, you can hit it with a pot from here. Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->BlueFire();}), Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return Here(RR_ICE_CAVERN_MQ_HUB, []{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);});}), - Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, []{return logic->IsAdult && logic->BlueFire();}), + Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, []{return (logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())) && logic->BlueFire();}), Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, []{return logic->BlueFire();}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index ac570543e..590af4d93 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -62,7 +62,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)) || (logic->IsAdult && logic->CanGroundJump())), LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), @@ -74,7 +74,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())) && logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, { @@ -232,7 +232,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || logic->CanGroundJump()), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 4e29f7e6d..0e460cabd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -94,6 +94,7 @@ void RegionTable_Init_GerudoFortress() { Entrance(RR_GF_NEAR_GROTTO, []{return true;}), Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true /* logic->CanClimb() */;}), Entrance(RR_GF_ABOVE_GTG, []{return true;}), + Entrance(RR_GF_BELOW_GS, []{return logic->IsAdult && logic->CanGroundJump();}), }); areaTable[RR_GF_TOP_OF_LOWER_VINES] = Region("GF Top of Lower Vines", SCENE_GERUDOS_FORTRESS, {}, {}, { @@ -114,7 +115,7 @@ void RegionTable_Init_GerudoFortress() { Entrance(RR_TH_KITCHEN_TOP, []{return true;}), Entrance(RR_GF_BOTTOM_OF_LOWER_VINES, []{return true;}), Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}), - Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult;}), + Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult || logic->CanGroundJump();}), Entrance(RR_GF_LONG_ROOF, []{return logic->CanUse(RG_HOVER_BOOTS) /* || bunny hood jump */ || logic->IsAdult && ctx->GetTrickOption(RT_GF_JUMP);}), Entrance(RR_GF_NEAR_CHEST, []{return logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GF_BELOW_GS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 58e6aedae..94a2c85c8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -111,7 +111,7 @@ void RegionTable_Init_Graveyard() { }, { //Exits Entrance(RR_THE_GRAVEYARD, []{return true;}), - Entrance(RR_KAK_WINDMILL, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}, false), + Entrance(RR_KAK_WINDMILL, []{return (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->IsChild && logic->CanGroundJump());}, false), }); areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Region("Graveyard Dampes House", SCENE_GRAVEKEEPERS_HUT, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 99d200efd..b1cefc144 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -24,7 +24,7 @@ void RegionTable_Init_HauntedWasteland() { //Locations LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), + LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang() || (logic->IsAdult && logic->CanGroundJump() && logic->CanJumpslash())), LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_3, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index d1e3807f5..a42f7af20 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -444,6 +444,11 @@ bool Logic::CanOpenOverworldDoor(RandomizerGet key) { return HasItem(key); } +bool Logic::CanGroundJump(bool hasBombflower) { + return ctx->GetTrickOption(RT_GROUND_JUMP) && CanStandingShield() && + (CanUse(RG_BOMB_BAG) || (hasBombflower && HasItem(RG_GORONS_BRACELET))); +} + bool Logic::CanOpenUnderwaterChest() { return ctx->GetTrickOption(RT_OPEN_UNDERWATER_CHEST) && CanUse(RG_IRON_BOOTS) && CanUse(RG_HOOKSHOT); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 03be61296..508db91ba 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -42,6 +42,7 @@ class Logic { bool HasBossSoul(RandomizerGet itemName); bool CanOpenOverworldDoor(RandomizerGet itemName); bool SmallKeys(s16 scene, uint8_t requiredAmount); + bool CanGroundJump(bool hasBombflower = false); bool CanOpenUnderwaterChest(); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 4469e909c..85a77416e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3896,6 +3896,7 @@ typedef enum { RT_FW_VOID_WARP, RT_GROUND_CLIP, RT_GROUND_JUMP, + RT_GROUND_JUMP_HARD, RT_HESS, RT_HOOKSHOT_CLIP, RT_HOOKSHOT_JUMP, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 818ac5ebf..73ab7aa9e 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -361,9 +361,7 @@ void Settings::CreateOptions() { // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, // Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); OPT_TRICK(RT_GROUND_CLIP, // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", - // "Enables locations requiring ground clips."); OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, - // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Jump", "Enables locations - // requiring ground jumps."); OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // "Enables locations requiring ground clips."); OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super // Slide."); OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, // Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring Hookshot clips."); @@ -417,6 +415,13 @@ void Settings::CreateOptions() { "- Retrieving DMT Gold Skulltula beside bomb flower\n" "- Hitting switch through wall in Spirit Temple's big mirror room with Bow, Slingshot, or Hookshot\n" "- Hitting switch through wall in Spirit Trial with Bow or Slingshot"); + OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Ground Jump", + "Enables requiring ground jumps."); + OPT_TRICK(RT_GROUND_JUMP_HARD, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE, Tricks::Tag::GLITCH }, + "Hard Ground Jumps", + "Enables ground jumps which require some precision outside of setting up jump:\n- While using Hover " + "Boots in Forest Temple Courtyard to reach upper ledge\n- While using Hover Boots in Shadow Temple " + "invisible spike room to reach door\n- Jumping past second step in Ice Cavern"); OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, { Tricks::Tag::NOVICE }, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); From 0973a4211e052526b3f20e5558c238250d6d9d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 7 Oct 2025 16:23:18 +0000 Subject: [PATCH 88/98] Fix grass graphic in Shuffle Grass (#5831) Previously rendering grass as wrong kind in MQ Dodongo room above stairs Updated code to match decomp logic --- soh/soh/Enhancements/randomizer/ShuffleGrass.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index 27d42a148..b11b06f3e 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -15,11 +15,10 @@ extern PlayState* gPlayState; extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); void DrawTypeOfGrass(EnKusa* grassActor, Gfx* bushDList, Gfx* grassDList, PlayState* play) { - // Actor params is -255 for regrowable grass. - if (grassActor->actor.params == -255) { - Gfx_DrawDListOpa(play, grassDList); - } else { + if ((grassActor->actor.params & 3) == 0) { Gfx_DrawDListOpa(play, bushDList); + } else { + Gfx_DrawDListOpa(play, grassDList); } } From 82e2fbb43f00d0464c596288572d82274e5cec97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 9 Oct 2025 00:26:03 +0000 Subject: [PATCH 89/98] null audio engine (#5834) depends on https://github.com/Kenix3/libultraship/pull/909 --- libultraship | 2 +- soh/soh/SohGui/MenuTypes.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libultraship b/libultraship index d1bbd53e8..1972d91f0 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit d1bbd53e8a1d2a4d6cfcce588ed13aa8d0686909 +Subproject commit 1972d91f0bf7338aa896d63d40210ef465a17ef6 diff --git a/soh/soh/SohGui/MenuTypes.h b/soh/soh/SohGui/MenuTypes.h index 911b688d7..6dd9aca2c 100644 --- a/soh/soh/SohGui/MenuTypes.h +++ b/soh/soh/SohGui/MenuTypes.h @@ -263,6 +263,7 @@ struct MainMenuEntry { static const std::unordered_map audioBackendsMap = { { Ship::AudioBackend::WASAPI, "Windows Audio Session API" }, { Ship::AudioBackend::SDL, "SDL" }, + { Ship::AudioBackend::NUL, "Null" }, }; static const std::unordered_map windowBackendsMap = { From 7700b34646abc7e5edb83f0d2a7d0f8ad52e3419 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya0@users.noreply.github.com> Date: Thu, 9 Oct 2025 01:49:33 -0400 Subject: [PATCH 90/98] bump otrexporter (#5835) --- OTRExporter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OTRExporter b/OTRExporter index 461ab19a3..33f20ca36 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit 461ab19a36cde807591543397e136cae19aa6e7c +Subproject commit 33f20ca367dc036291df9cb9a9304c542deb66f9 From 57c368aa2c7ecb2c7d85f1f52ea7c0ea7d5c2d69 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya0@users.noreply.github.com> Date: Thu, 9 Oct 2025 19:50:51 -0400 Subject: [PATCH 91/98] update lus includes for new LUS file structure (#5820) * Bump LUS to include FileDropMgr's new registration system and initial cursor visibility changes. * New LUS ref. * Remove default on for cursor always visible. Add option to camera controls next to enable mouse input for autocapture. Set autocapture on startup. * next LUS * clang again * Add "EnableMouse" CVar check to startup SetAutoCaptureMouse. * Back to LUS main. * lus version with fixes we need * very wip * get it building * soh otr * bump lus before fixing soh side stuff * build * still builds * mac error * bump otrexporter * bump to lus main * upstream otrexporter --------- Co-authored-by: Malkierian Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> --- CMakeLists.txt | 4 +- OTRExporter | 2 +- libultraship | 2 +- soh/CMakeLists.txt | 24 ---------- soh/Resource.rc | 2 +- soh/include/functions.h | 2 +- soh/include/macros.h | 2 +- soh/include/z64audio.h | 2 +- soh/soh/Enhancements/Presets/Presets.cpp | 4 +- .../Restorations/GraveHoleJumps.cpp | 2 +- .../N64WeirdFrames/N64WeirdFrames.cpp | 2 +- .../N64WeirdFrames/WeirdAnimation.cpp | 4 +- .../Restorations/WideShutterDoorRanges.cpp | 2 +- .../Enhancements/audio/AudioCollection.cpp | 2 +- soh/soh/Enhancements/audio/AudioEditor.cpp | 2 +- soh/soh/Enhancements/controls/InputViewer.cpp | 5 ++- soh/soh/Enhancements/controls/Mouse.cpp | 2 +- .../controls/SohInputEditorWindow.cpp | 6 +-- soh/soh/Enhancements/debugconsole.cpp | 8 ++-- soh/soh/Enhancements/debugger/MessageViewer.h | 2 +- .../Enhancements/debugger/SohConsoleWindow.h | 4 +- .../debugger/SohGfxDebuggerWindow.h | 4 +- soh/soh/Enhancements/debugger/dlViewer.cpp | 5 ++- soh/soh/Enhancements/kaleido.cpp | 2 +- soh/soh/Enhancements/mod_menu.cpp | 2 +- .../randomizer/3drando/rando_main.cpp | 2 +- .../randomizer/3drando/spoiler_log.cpp | 4 +- .../Enhancements/randomizer/fishsanity.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- soh/soh/Enhancements/randomizer/option.cpp | 2 +- .../Enhancements/randomizer/randomizer.cpp | 2 +- .../randomizer/randomizer_check_tracker.cpp | 1 + .../randomizer/randomizer_item_tracker.cpp | 1 + soh/soh/Enhancements/randomizer/settings.cpp | 2 +- .../Enhancements/timesplits/TimeSplits.cpp | 2 +- soh/soh/Enhancements/tts/tts.cpp | 4 +- soh/soh/Extractor/Extract.cpp | 2 +- soh/soh/OTRGlobals.cpp | 44 ++++++++++--------- soh/soh/OTRGlobals.h | 2 +- soh/soh/ResourceManagerHelpers.cpp | 5 ++- soh/soh/ResourceManagerHelpers.h | 2 +- soh/soh/SohGui/ImGuiUtils.cpp | 4 +- soh/soh/SohGui/Menu.cpp | 4 +- soh/soh/SohGui/Menu.h | 2 +- soh/soh/SohGui/ResolutionEditor.cpp | 4 +- soh/soh/SohGui/SohGui.cpp | 2 +- soh/soh/SohGui/SohMenu.cpp | 6 +-- soh/soh/SohGui/SohMenu.h | 2 +- soh/soh/SohGui/SohMenuBar.cpp | 4 +- soh/soh/SohGui/SohMenuBar.h | 4 +- soh/soh/SohGui/SohModals.h | 4 +- .../resource/importer/AnimationFactory.cpp | 4 +- soh/soh/resource/importer/AnimationFactory.h | 4 +- soh/soh/resource/importer/ArrayFactory.cpp | 2 +- soh/soh/resource/importer/ArrayFactory.h | 4 +- .../resource/importer/AudioSampleFactory.cpp | 6 +-- .../resource/importer/AudioSampleFactory.h | 6 +-- .../importer/AudioSequenceFactory.cpp | 8 ++-- .../resource/importer/AudioSequenceFactory.h | 6 +-- .../importer/AudioSoundFontFactory.cpp | 6 +-- .../resource/importer/AudioSoundFontFactory.h | 6 +-- soh/soh/resource/importer/BackgroundFactory.h | 4 +- .../importer/CollisionHeaderFactory.h | 6 +-- soh/soh/resource/importer/CutsceneFactory.h | 4 +- soh/soh/resource/importer/PathFactory.h | 6 +-- .../importer/PlayerAnimationFactory.h | 4 +- soh/soh/resource/importer/SceneFactory.h | 6 +-- soh/soh/resource/importer/SkeletonFactory.h | 6 +-- .../resource/importer/SkeletonLimbFactory.h | 6 +-- soh/soh/resource/importer/TextFactory.h | 6 +-- .../scenecommand/SceneCommandFactory.h | 6 +-- soh/soh/resource/logging/PathLogger.h | 2 +- .../resource/logging/SceneCommandLoggers.h | 2 +- soh/soh/resource/type/Animation.h | 2 +- soh/soh/resource/type/Array.cpp | 2 +- soh/soh/resource/type/Array.h | 2 +- soh/soh/resource/type/AudioSample.h | 2 +- soh/soh/resource/type/AudioSequence.h | 2 +- soh/soh/resource/type/AudioSoundFont.h | 2 +- soh/soh/resource/type/Background.h | 2 +- soh/soh/resource/type/CollisionHeader.h | 2 +- soh/soh/resource/type/Cutscene.h | 2 +- soh/soh/resource/type/Path.h | 2 +- soh/soh/resource/type/PlayerAnimation.h | 2 +- soh/soh/resource/type/Scene.h | 2 +- soh/soh/resource/type/Skeleton.cpp | 2 +- soh/soh/resource/type/Skeleton.h | 2 +- soh/soh/resource/type/SkeletonLimb.h | 2 +- soh/soh/resource/type/Text.h | 2 +- .../resource/type/scenecommand/EndMarker.h | 2 +- .../resource/type/scenecommand/SceneCommand.h | 2 +- .../resource/type/scenecommand/SetActorList.h | 2 +- .../type/scenecommand/SetAlternateHeaders.h | 2 +- .../type/scenecommand/SetCameraSettings.h | 2 +- .../type/scenecommand/SetCollisionHeader.h | 2 +- .../resource/type/scenecommand/SetCsCamera.h | 2 +- .../resource/type/scenecommand/SetCutscenes.h | 2 +- .../type/scenecommand/SetEchoSettings.h | 2 +- .../type/scenecommand/SetEntranceList.h | 2 +- .../resource/type/scenecommand/SetExitList.h | 2 +- .../resource/type/scenecommand/SetLightList.h | 2 +- .../type/scenecommand/SetLightingSettings.h | 2 +- soh/soh/resource/type/scenecommand/SetMesh.h | 2 +- .../type/scenecommand/SetObjectList.h | 2 +- .../resource/type/scenecommand/SetPathways.h | 2 +- .../type/scenecommand/SetRoomBehavior.h | 2 +- .../resource/type/scenecommand/SetRoomList.h | 2 +- .../type/scenecommand/SetSkyboxModifier.h | 2 +- .../type/scenecommand/SetSkyboxSettings.h | 2 +- .../type/scenecommand/SetSoundSettings.h | 2 +- .../type/scenecommand/SetSpecialObjects.h | 2 +- .../type/scenecommand/SetStartPositionList.h | 2 +- .../type/scenecommand/SetTimeSettings.h | 2 +- .../scenecommand/SetTransitionActorList.h | 2 +- .../type/scenecommand/SetWindSettings.h | 2 +- soh/soh/z_message_OTR.cpp | 2 +- soh/soh/z_play_otr.cpp | 4 +- soh/soh/z_scene_otr.cpp | 6 +-- soh/src/code/sys_ucode.c | 2 +- soh/src/code/z_room.c | 2 +- .../ovl_kaleido_scope/z_kaleido_map_PAL.c | 2 +- 121 files changed, 204 insertions(+), 221 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef00ae8f5..1a64e93b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,7 +198,7 @@ add_custom_target( # copy LUS default shaders into assets/custom COMMAND ${CMAKE_COMMAND} -E rm -r -f ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/graphic/Fast3D/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/fast/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$" --non-interactive --xml-root assets/xml --custom-otr-file soh.o2r "--custom-assets-path" ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom --port-ver "${CMAKE_PROJECT_VERSION}" COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake @@ -224,7 +224,7 @@ add_custom_target( # copy LUS default shaders into assets/custom COMMAND ${CMAKE_COMMAND} -E rm -r -f ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/graphic/Fast3D/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/fast/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/ COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$" --norom --custom-otr-file soh.o2r "--custom-assets-path" ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom --port-ver "${CMAKE_PROJECT_VERSION}" COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -DONLYSOHOTR=On -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake diff --git a/OTRExporter b/OTRExporter index 33f20ca36..32e088e28 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit 33f20ca367dc036291df9cb9a9304c542deb66f9 +Subproject commit 32e088e28c8cdd055d4bb8f3f219d33ad37963f3 diff --git a/libultraship b/libultraship index 1972d91f0..2782e554d 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 1972d91f0bf7338aa896d63d40210ef465a17ef6 +Subproject commit 2782e554d961be13db8d862c6ab48839b82f30ee diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index e6e2a3181..711dd8cb2 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -319,31 +319,7 @@ endif() target_include_directories(${PROJECT_NAME} PRIVATE assets ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${CMAKE_CURRENT_SOURCE_DIR}/src/ - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/include - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/log - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/debug - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/menu - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/utils - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/utils/binarytools - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource/type - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource/factory - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/audio - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/window - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/window/gui - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public/libultra - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public/bridge - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern/tinyxml2 - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/ - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/ - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic/Fast3D/U64/PR - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic ${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type ${SDL2-INCLUDE} ${SDL2-NET-INCLUDE} diff --git a/soh/Resource.rc b/soh/Resource.rc index 7d9f356d0..59702663f 100644 --- a/soh/Resource.rc +++ b/soh/Resource.rc @@ -1,6 +1,6 @@ // Microsoft Visual C++ generated resource script. // -#include "resource.h" +#include #include "properties.h" #define APSTUDIO_READONLY_SYMBOLS diff --git a/soh/include/functions.h b/soh/include/functions.h index 8deb36953..75797401e 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -10,7 +10,7 @@ extern "C" { #endif -#include "luslog.h" +#include #include #if defined(INCLUDE_GAME_PRINTF) && defined(_DEBUG) diff --git a/soh/include/macros.h b/soh/include/macros.h index 325fb91b6..acac5cd49 100644 --- a/soh/include/macros.h +++ b/soh/include/macros.h @@ -1,7 +1,7 @@ #ifndef MACROS_H #define MACROS_H -#include +#include // Upstream TODO: Document reasoning for change // #ifndef __GNUC__ diff --git a/soh/include/z64audio.h b/soh/include/z64audio.h index c562b820f..cbd82fcf2 100644 --- a/soh/include/z64audio.h +++ b/soh/include/z64audio.h @@ -5,7 +5,7 @@ extern "C" { #endif -#include +#include #define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0)) diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index b8503cbc6..75ff9aabd 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -2,11 +2,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include "soh/OTRGlobals.h" #include "soh/SohGui/MenuTypes.h" #include "soh/SohGui/SohMenu.h" diff --git a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp index 32157b5ce..760c3c903 100644 --- a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp +++ b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp @@ -1,4 +1,4 @@ -#include "public/bridge/consolevariablebridge.h" +#include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" #include "functions.h" diff --git a/soh/soh/Enhancements/Restorations/N64WeirdFrames/N64WeirdFrames.cpp b/soh/soh/Enhancements/Restorations/N64WeirdFrames/N64WeirdFrames.cpp index 0e6b1cbf3..33bf12c3c 100644 --- a/soh/soh/Enhancements/Restorations/N64WeirdFrames/N64WeirdFrames.cpp +++ b/soh/soh/Enhancements/Restorations/N64WeirdFrames/N64WeirdFrames.cpp @@ -1,4 +1,4 @@ -#include "public/bridge/consolevariablebridge.h" +#include #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/ShipInit.hpp" diff --git a/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp b/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp index bd812c658..c4cbc4bfe 100644 --- a/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp +++ b/soh/soh/Enhancements/Restorations/N64WeirdFrames/WeirdAnimation.cpp @@ -1,7 +1,7 @@ #include "WeirdAnimation.h" -#include "resource/ResourceManager.h" -#include "Context.h" +#include +#include #include #include diff --git a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp index 8f5fc4f30..78339a48b 100644 --- a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp +++ b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp @@ -1,4 +1,4 @@ -#include "public/bridge/consolevariablebridge.h" +#include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index a30d3f086..ab7a8d95a 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -4,7 +4,7 @@ #include "soh/cvar_prefixes.h" #include "soh/Notification/Notification.h" #include -#include +#include #include #include #include diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index c64ed7b42..5a7fb1414 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -10,7 +10,7 @@ #include "../randomizer/3drando/random.hpp" #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" -#include +#include #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" #include "AudioCollection.h" diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index 1fbab40c2..2f73fb057 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -1,8 +1,9 @@ #include "InputViewer.h" -#include "public/bridge/consolevariablebridge.h" +#include #include "libultraship/libultra/controller.h" -#include "Context.h" +#include +#include #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" #include diff --git a/soh/soh/Enhancements/controls/Mouse.cpp b/soh/soh/Enhancements/controls/Mouse.cpp index 4ad9d11d0..87af5168b 100644 --- a/soh/soh/Enhancements/controls/Mouse.cpp +++ b/soh/soh/Enhancements/controls/Mouse.cpp @@ -2,7 +2,7 @@ #include "soh/OTRGlobals.h" #include "z64player.h" #include "global.h" -#include +#include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index 95af88a74..bdfe6c1c1 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -1,13 +1,13 @@ #include "SohInputEditorWindow.h" -#include -#include "graphic/Fast3D/Fast3dWindow.h" +#include +#include #include "soh/OTRGlobals.h" #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" #include "z64.h" #include "soh/cvar_prefixes.h" #ifndef __WIIU__ -#include "controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h" +#include #endif #define SCALE_IMGUI_SIZE(value) ((value / 13.0f) * ImGui::GetFontSize()) diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 7713b48b8..ff40f149a 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -1,5 +1,5 @@ #include "debugconsole.h" -#include +#include #include "savestates.h" #include "soh/ActorDB.h" @@ -15,10 +15,10 @@ #define Path _Path #define PATH_HACK -#include +#include -#include -#include +#include +#include #include #include #undef PATH_HACK diff --git a/soh/soh/Enhancements/debugger/MessageViewer.h b/soh/soh/Enhancements/debugger/MessageViewer.h index 9ce8eab05..1d2c8fa83 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.h +++ b/soh/soh/Enhancements/debugger/MessageViewer.h @@ -3,7 +3,7 @@ #include "z64.h" #ifdef __cplusplus -#include "GuiWindow.h" +#include #include extern "C" { #endif diff --git a/soh/soh/Enhancements/debugger/SohConsoleWindow.h b/soh/soh/Enhancements/debugger/SohConsoleWindow.h index db039625b..b84399ad6 100644 --- a/soh/soh/Enhancements/debugger/SohConsoleWindow.h +++ b/soh/soh/Enhancements/debugger/SohConsoleWindow.h @@ -1,8 +1,8 @@ #ifndef SOH_CONSOLE_H #define SOH_CONSOLE_H -#include "window/gui/GuiWindow.h" -#include "window/gui/ConsoleWindow.h" +#include +#include class SohConsoleWindow : public Ship::ConsoleWindow { public: diff --git a/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.h b/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.h index 789173b88..7b9267693 100644 --- a/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.h +++ b/soh/soh/Enhancements/debugger/SohGfxDebuggerWindow.h @@ -1,8 +1,8 @@ #ifndef SOH_GFX_DEBUGGER_H #define SOH_GFX_DEBUGGER_H -#include "window/gui/GuiWindow.h" -#include "window/gui/GfxDebuggerWindow.h" +#include +#include class SohGfxDebuggerWindow : public LUS::GfxDebuggerWindow { public: diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index a02aa7d95..60a6e07c8 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -2,8 +2,9 @@ #include "soh/util.h" #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" -#include "ResourceManager.h" -#include "DisplayList.h" +#include +#include +#include #include "soh/OTRGlobals.h" #include diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index eef19b495..2b9552263 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -16,7 +16,7 @@ extern PlayState* gPlayState; #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh_assets.h" #include "textures/icon_item_static/icon_item_static.h" -#include "consolevariablebridge.h" +#include #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include diff --git a/soh/soh/Enhancements/mod_menu.cpp b/soh/soh/Enhancements/mod_menu.cpp index 427f5b2b4..feb412350 100644 --- a/soh/soh/Enhancements/mod_menu.cpp +++ b/soh/soh/Enhancements/mod_menu.cpp @@ -1,5 +1,5 @@ #include "mod_menu.h" -#include "utils/StringHelper.h" +#include #include #include "soh/SohGui/SohGui.hpp" #include "soh/OTRGlobals.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 51cfdd535..28f8537b4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -5,7 +5,7 @@ #include "rando_main.hpp" #include "../context.h" #include -#include +#include #include #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 3c91a1f70..b3e71e8f0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -26,10 +26,10 @@ #include #include -#include +#include #include -#include "consolevariablebridge.h" +#include using json = nlohmann::ordered_json; using namespace Rando; diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index e34799156..83d326384 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -5,7 +5,7 @@ #include "variables.h" #include "functions.h" #include "macros.h" -#include +#include extern "C" { #include "src/overlays/actors/ovl_Fishing/z_fishing.h" diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index a42f7af20..17a665624 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -13,7 +13,7 @@ #include "macros.h" #include "variables.h" #include -#include "StringHelper.h" +#include #include "soh/resource/type/Scene.h" #include "soh/resource/type/scenecommand/SetTransitionActorList.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h" diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index f027fd066..bfdecd861 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -1,6 +1,6 @@ #include "option.h" #include "libultraship/bridge.h" -#include +#include #include #include "soh/SohGui/SohGui.hpp" #include "soh/SohGui/UIWidgets.hpp" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 345c27ab8..6d0047ec9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -27,7 +27,7 @@ #include #include "draw.h" #include "soh/OTRGlobals.h" -#include "window/FileDropMgr.h" +#include #include "soh/SohGui/UIWidgets.hpp" #include "static_data.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index aab671088..a907fdab4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "location.h" #include "item_location.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 9e5a9be89..b3acc96d5 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "randomizer_check_tracker.h" #include "randomizer_item_tracker.h" diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 73ab7aa9e..8efd6c1f9 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -8,7 +8,7 @@ #include -#include "consolevariablebridge.h" +#include namespace Rando { std::shared_ptr Settings::mInstance; diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index e6515ed82..3f06450f7 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -2,7 +2,7 @@ #include #include -#include "Context.h" +#include #include "TimeSplits.h" #include "soh/Enhancements/gameplaystats.h" #include "soh/SaveManager.h" diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index 1dc8a1ba6..612d4172c 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -2,8 +2,8 @@ #include "soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include -#include -#include +#include +#include #include #include #include diff --git a/soh/soh/Extractor/Extract.cpp b/soh/soh/Extractor/Extract.cpp index a12be6264..fecf9b741 100644 --- a/soh/soh/Extractor/Extract.cpp +++ b/soh/soh/Extractor/Extract.cpp @@ -6,7 +6,7 @@ #endif #include "Extract.h" #include "portable-file-dialogs.h" -#include +#include #include "variables.h" #ifdef unix diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index a0ffdc1d1..3358d8585 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -7,10 +7,10 @@ #include #include "ResourceManagerHelpers.h" -#include "graphic/Fast3D/Fast3dWindow.h" -#include -#include -#include +#include +#include +#include +#include #include #include "Enhancements/gameconsole.h" @@ -19,7 +19,7 @@ #else #include #endif -#include +#include #include "Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include "Enhancements/controls/SohInputEditorWindow.h" #include "Enhancements/cosmetics/CosmeticsEditor.h" @@ -40,10 +40,10 @@ #include "variables.h" #include "z64.h" #include "macros.h" -#include "Fonts.h" -#include "window/FileDropMgr.h" -#include "window/gui/resource/Font.h" -#include +#include +#include +#include +#include #include "Enhancements/custom-message/CustomMessageManager.h" #include "Enhancements/Presets/Presets.h" #include "util.h" @@ -52,7 +52,7 @@ #include "Extractor/Extract.h" #endif -#include +#include #ifdef __APPLE__ #include @@ -86,14 +86,16 @@ Sail* Sail::Instance; #include "Enhancements/game-interactor/GameInteractor.h" #include "Enhancements/randomizer/draw.h" #include +#include +#include // Resource Types/Factories -#include "resource/type/Array.h" -#include "resource/type/Blob.h" -#include "resource/type/DisplayList.h" -#include "resource/type/Matrix.h" -#include "resource/type/Texture.h" -#include "resource/type/Vertex.h" +#include "soh/resource/type/Array.h" +#include +#include +#include +#include +#include #include "soh/resource/type/SohResourceType.h" #include "soh/resource/type/Animation.h" #include "soh/resource/type/AudioSample.h" @@ -107,11 +109,11 @@ Sail* Sail::Instance; #include "soh/resource/type/Skeleton.h" #include "soh/resource/type/SkeletonLimb.h" #include "soh/resource/type/Text.h" -#include "resource/factory/BlobFactory.h" -#include "resource/factory/DisplayListFactory.h" -#include "resource/factory/MatrixFactory.h" -#include "resource/factory/TextureFactory.h" -#include "resource/factory/VertexFactory.h" +#include +#include +#include +#include +#include #include "soh/resource/importer/ArrayFactory.h" #include "soh/resource/importer/AnimationFactory.h" #include "soh/resource/importer/AudioSampleFactory.h" diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 032686f8e..b653e9edf 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -21,7 +21,7 @@ #define M_SQRT1_2f 0.70710678118654752440f /* 1/sqrt(2) */ #ifdef __cplusplus -#include +#include #include "Enhancements/savestates.h" #include "Enhancements/randomizer/randomizer.h" #include diff --git a/soh/soh/ResourceManagerHelpers.cpp b/soh/soh/ResourceManagerHelpers.cpp index a9ec6fc25..127378da7 100644 --- a/soh/soh/ResourceManagerHelpers.cpp +++ b/soh/soh/ResourceManagerHelpers.cpp @@ -11,8 +11,9 @@ #include "resource/type/Array.h" #include "resource/type/Skeleton.h" #include "resource/type/PlayerAnimation.h" -#include -#include +#include +#include +#include extern "C" PlayState* gPlayState; diff --git a/soh/soh/ResourceManagerHelpers.h b/soh/soh/ResourceManagerHelpers.h index b760feae3..8562a3e0e 100644 --- a/soh/soh/ResourceManagerHelpers.h +++ b/soh/soh/ResourceManagerHelpers.h @@ -10,7 +10,7 @@ #ifdef __cplusplus #include -#include +#include std::shared_ptr ResourceMgr_GetResourceByNameHandlingMQ(const char* path); diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index ab3d8f59c..c80293a53 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -1,6 +1,6 @@ #include "ImGuiUtils.h" -#include -#include +#include +#include #include "assets/soh_assets.h" #include "soh/Enhancements/randomizer/rando_hash.h" diff --git a/soh/soh/SohGui/Menu.cpp b/soh/soh/SohGui/Menu.cpp index aa83c314b..592c0c5e6 100644 --- a/soh/soh/SohGui/Menu.cpp +++ b/soh/soh/SohGui/Menu.cpp @@ -2,8 +2,8 @@ #include "UIWidgets.hpp" #include "soh/OTRGlobals.h" #include "soh/Enhancements/controls/SohInputEditorWindow.h" -#include "window/gui/GuiMenuBar.h" -#include "window/gui/GuiElement.h" +#include +#include #include "SohModals.h" #include #include diff --git a/soh/soh/SohGui/Menu.h b/soh/soh/SohGui/Menu.h index 1af541b8d..a39d48510 100644 --- a/soh/soh/SohGui/Menu.h +++ b/soh/soh/SohGui/Menu.h @@ -2,7 +2,7 @@ #define MENU_H #include -#include "graphic/Fast3D/backends/gfx_rendering_api.h" +#include #include "MenuTypes.h" namespace Ship { diff --git a/soh/soh/SohGui/ResolutionEditor.cpp b/soh/soh/SohGui/ResolutionEditor.cpp index e568287b2..232458d9a 100644 --- a/soh/soh/SohGui/ResolutionEditor.cpp +++ b/soh/soh/SohGui/ResolutionEditor.cpp @@ -3,8 +3,8 @@ #include #include "soh/SohGui/UIWidgets.hpp" -#include -#include +#include +#include #include "soh/OTRGlobals.h" #include "soh/SohGui/SohMenu.h" #include "soh/SohGui/SohGui.hpp" diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index cf9182a62..23befb2f3 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -13,7 +13,7 @@ #include #ifdef __APPLE__ -#include "graphic/Fast3D/backends/gfx_metal.h" +#include #endif #ifdef __SWITCH__ diff --git a/soh/soh/SohGui/SohMenu.cpp b/soh/soh/SohGui/SohMenu.cpp index 547025391..78616be7e 100644 --- a/soh/soh/SohGui/SohMenu.cpp +++ b/soh/soh/SohGui/SohMenu.cpp @@ -1,10 +1,10 @@ #include "SohMenu.h" #include "soh/OTRGlobals.h" #include "soh/Enhancements/controls/SohInputEditorWindow.h" -#include "window/gui/GuiMenuBar.h" -#include "window/gui/GuiElement.h" +#include +#include #include -#include "StringHelper.h" +#include #include #include diff --git a/soh/soh/SohGui/SohMenu.h b/soh/soh/SohGui/SohMenu.h index ec5f7705c..d6833f28b 100644 --- a/soh/soh/SohGui/SohMenu.h +++ b/soh/soh/SohGui/SohMenu.h @@ -4,7 +4,7 @@ #include #include "UIWidgets.hpp" #include "Menu.h" -#include "graphic/Fast3D/backends/gfx_rendering_api.h" +#include #include "soh/cvar_prefixes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/Presets/Presets.h" diff --git a/soh/soh/SohGui/SohMenuBar.cpp b/soh/soh/SohGui/SohMenuBar.cpp index 418d02eb5..debfc9cf5 100644 --- a/soh/soh/SohGui/SohMenuBar.cpp +++ b/soh/soh/SohGui/SohMenuBar.cpp @@ -1,11 +1,11 @@ #include "SohMenuBar.h" #include #include "regex" -#include "public/bridge/consolevariablebridge.h" +#include #include #include "UIWidgets.hpp" #include "include/z64audio.h" -#include "graphic/Fast3D/backends/gfx_rendering_api.h" +#include #include "soh/OTRGlobals.h" #include "soh/SaveManager.h" #include "z64.h" diff --git a/soh/soh/SohGui/SohMenuBar.h b/soh/soh/SohGui/SohMenuBar.h index 8c078e08f..56d0c1c6a 100644 --- a/soh/soh/SohGui/SohMenuBar.h +++ b/soh/soh/SohGui/SohMenuBar.h @@ -1,8 +1,8 @@ #pragma once #include -#include "window/gui/GuiMenuBar.h" -#include "window/gui/GuiElement.h" +#include +#include namespace SohGui { class SohMenuBar : public Ship::GuiMenuBar { diff --git a/soh/soh/SohGui/SohModals.h b/soh/soh/SohGui/SohModals.h index f74f0b1bf..68a9b8510 100644 --- a/soh/soh/SohGui/SohModals.h +++ b/soh/soh/SohGui/SohModals.h @@ -1,8 +1,8 @@ #pragma once #include -#include "window/gui/GuiMenuBar.h" -#include "window/gui/GuiElement.h" +#include +#include class SohModalWindow final : public Ship::GuiWindow { public: diff --git a/soh/soh/resource/importer/AnimationFactory.cpp b/soh/soh/resource/importer/AnimationFactory.cpp index d6adfb66c..99507e4f3 100644 --- a/soh/soh/resource/importer/AnimationFactory.cpp +++ b/soh/soh/resource/importer/AnimationFactory.cpp @@ -1,8 +1,8 @@ #include "soh/resource/importer/AnimationFactory.h" #include "soh/resource/type/Animation.h" -#include "ResourceManager.h" +#include #include "spdlog/spdlog.h" -#include "Context.h" +#include namespace SOH { std::shared_ptr diff --git a/soh/soh/resource/importer/AnimationFactory.h b/soh/soh/resource/importer/AnimationFactory.h index 2312d7ad3..a28d7512c 100644 --- a/soh/soh/resource/importer/AnimationFactory.h +++ b/soh/soh/resource/importer/AnimationFactory.h @@ -1,7 +1,7 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" +#include +#include namespace SOH { class ResourceFactoryBinaryAnimationV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/ArrayFactory.cpp b/soh/soh/resource/importer/ArrayFactory.cpp index 0762704ff..0e1b2ac04 100644 --- a/soh/soh/resource/importer/ArrayFactory.cpp +++ b/soh/soh/resource/importer/ArrayFactory.cpp @@ -1,7 +1,7 @@ #include "soh/resource/importer/ArrayFactory.h" #include "soh/resource/type/Array.h" #include "spdlog/spdlog.h" -#include "graphic/Fast3D/lus_gbi.h" +#include namespace SOH { std::shared_ptr diff --git a/soh/soh/resource/importer/ArrayFactory.h b/soh/soh/resource/importer/ArrayFactory.h index a64b7a821..aae282754 100644 --- a/soh/soh/resource/importer/ArrayFactory.h +++ b/soh/soh/resource/importer/ArrayFactory.h @@ -1,7 +1,7 @@ #pragma once -#include "resource/Resource.h" -#include "resource/ResourceFactoryBinary.h" +#include +#include namespace SOH { class ResourceFactoryBinaryArrayV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/AudioSampleFactory.cpp b/soh/soh/resource/importer/AudioSampleFactory.cpp index 9fd8d746a..098efd236 100644 --- a/soh/soh/resource/importer/AudioSampleFactory.cpp +++ b/soh/soh/resource/importer/AudioSampleFactory.cpp @@ -4,9 +4,9 @@ #include "spdlog/spdlog.h" #include "z64.h" #include "z64audio.h" -#include "Context.h" -#include "resource/archive/Archive.h" -#include "resource/ResourceManager.h" +#include +#include +#include #define DR_WAV_IMPLEMENTATION #include diff --git a/soh/soh/resource/importer/AudioSampleFactory.h b/soh/soh/resource/importer/AudioSampleFactory.h index b750da4f1..e48d21be2 100644 --- a/soh/soh/resource/importer/AudioSampleFactory.h +++ b/soh/soh/resource/importer/AudioSampleFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinaryAudioSampleV2 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/AudioSequenceFactory.cpp b/soh/soh/resource/importer/AudioSequenceFactory.cpp index 850c27c16..313284f6a 100644 --- a/soh/soh/resource/importer/AudioSequenceFactory.cpp +++ b/soh/soh/resource/importer/AudioSequenceFactory.cpp @@ -2,12 +2,12 @@ #include "soh/resource/importer/AudioSoundFontFactory.h" #include "soh/resource/type/AudioSequence.h" #include "spdlog/spdlog.h" -#include "resource/ResourceManager.h" +#include #include -#include "Context.h" -#include "resource/archive/Archive.h" -#include "BinaryWriter.h" +#include +#include +#include #include namespace SOH { diff --git a/soh/soh/resource/importer/AudioSequenceFactory.h b/soh/soh/resource/importer/AudioSequenceFactory.h index 4ae249ec3..897b49c50 100644 --- a/soh/soh/resource/importer/AudioSequenceFactory.h +++ b/soh/soh/resource/importer/AudioSequenceFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinaryAudioSequenceV2 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/AudioSoundFontFactory.cpp b/soh/soh/resource/importer/AudioSoundFontFactory.cpp index 1150b2b69..f71f31d14 100644 --- a/soh/soh/resource/importer/AudioSoundFontFactory.cpp +++ b/soh/soh/resource/importer/AudioSoundFontFactory.cpp @@ -3,9 +3,9 @@ #include #include #include "z64audio.h" -#include "Context.h" -#include "resource/archive/Archive.h" -#include "resource/ResourceManager.h" +#include +#include +#include namespace SOH { std::shared_ptr diff --git a/soh/soh/resource/importer/AudioSoundFontFactory.h b/soh/soh/resource/importer/AudioSoundFontFactory.h index 0a56769cd..30d3e620f 100644 --- a/soh/soh/resource/importer/AudioSoundFontFactory.h +++ b/soh/soh/resource/importer/AudioSoundFontFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include #include "soh/resource/type/AudioSoundFont.h" namespace SOH { diff --git a/soh/soh/resource/importer/BackgroundFactory.h b/soh/soh/resource/importer/BackgroundFactory.h index e9a47a952..645174c69 100644 --- a/soh/soh/resource/importer/BackgroundFactory.h +++ b/soh/soh/resource/importer/BackgroundFactory.h @@ -1,7 +1,7 @@ #pragma once -#include "resource/Resource.h" -#include "resource/ResourceFactoryBinary.h" +#include +#include namespace SOH { class ResourceFactoryBinaryBackgroundV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.h b/soh/soh/resource/importer/CollisionHeaderFactory.h index 4db21d351..45076f1a6 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.h +++ b/soh/soh/resource/importer/CollisionHeaderFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinaryCollisionHeaderV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/CutsceneFactory.h b/soh/soh/resource/importer/CutsceneFactory.h index 95a6f379e..be44c4686 100644 --- a/soh/soh/resource/importer/CutsceneFactory.h +++ b/soh/soh/resource/importer/CutsceneFactory.h @@ -1,7 +1,7 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" +#include +#include namespace SOH { class ResourceFactoryBinaryCutsceneV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/PathFactory.h b/soh/soh/resource/importer/PathFactory.h index f94a201c5..9c83f5183 100644 --- a/soh/soh/resource/importer/PathFactory.h +++ b/soh/soh/resource/importer/PathFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinaryPathV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/PlayerAnimationFactory.h b/soh/soh/resource/importer/PlayerAnimationFactory.h index 7761c63b6..09cbb3358 100644 --- a/soh/soh/resource/importer/PlayerAnimationFactory.h +++ b/soh/soh/resource/importer/PlayerAnimationFactory.h @@ -1,7 +1,7 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" +#include +#include namespace SOH { class ResourceFactoryBinaryPlayerAnimationV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/SceneFactory.h b/soh/soh/resource/importer/SceneFactory.h index a22291d51..11de07520 100644 --- a/soh/soh/resource/importer/SceneFactory.h +++ b/soh/soh/resource/importer/SceneFactory.h @@ -3,9 +3,9 @@ #include "soh/resource/type/Scene.h" #include "soh/resource/type/scenecommand/SceneCommand.h" #include "soh/resource/importer/scenecommand/SceneCommandFactory.h" -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinarySceneV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/SkeletonFactory.h b/soh/soh/resource/importer/SkeletonFactory.h index b7c90443f..209e2380d 100644 --- a/soh/soh/resource/importer/SkeletonFactory.h +++ b/soh/soh/resource/importer/SkeletonFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinarySkeletonV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/SkeletonLimbFactory.h b/soh/soh/resource/importer/SkeletonLimbFactory.h index bcf1fd4d5..3f1b76b1c 100644 --- a/soh/soh/resource/importer/SkeletonLimbFactory.h +++ b/soh/soh/resource/importer/SkeletonLimbFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinarySkeletonLimbV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/TextFactory.h b/soh/soh/resource/importer/TextFactory.h index b67f07cbb..502549600 100644 --- a/soh/soh/resource/importer/TextFactory.h +++ b/soh/soh/resource/importer/TextFactory.h @@ -1,8 +1,8 @@ #pragma once -#include "Resource.h" -#include "ResourceFactoryBinary.h" -#include "ResourceFactoryXML.h" +#include +#include +#include namespace SOH { class ResourceFactoryBinaryTextV0 final : public Ship::ResourceFactoryBinary { diff --git a/soh/soh/resource/importer/scenecommand/SceneCommandFactory.h b/soh/soh/resource/importer/scenecommand/SceneCommandFactory.h index b1cd67ae6..6a038fa83 100644 --- a/soh/soh/resource/importer/scenecommand/SceneCommandFactory.h +++ b/soh/soh/resource/importer/scenecommand/SceneCommandFactory.h @@ -1,10 +1,10 @@ #pragma once #include -#include "Resource.h" -#include "ResourceFactory.h" +#include +#include #include "soh/resource/type/scenecommand/SceneCommand.h" -#include "public/bridge/consolevariablebridge.h" +#include namespace SOH { class SceneCommandFactoryBinaryV0 { diff --git a/soh/soh/resource/logging/PathLogger.h b/soh/soh/resource/logging/PathLogger.h index f239d5747..23f4f0d30 100644 --- a/soh/soh/resource/logging/PathLogger.h +++ b/soh/soh/resource/logging/PathLogger.h @@ -1,4 +1,4 @@ -#include "Resource.h" +#include #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" diff --git a/soh/soh/resource/logging/SceneCommandLoggers.h b/soh/soh/resource/logging/SceneCommandLoggers.h index b006b9c0a..64dc1d995 100644 --- a/soh/soh/resource/logging/SceneCommandLoggers.h +++ b/soh/soh/resource/logging/SceneCommandLoggers.h @@ -1,4 +1,4 @@ -#include "Resource.h" +#include #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" diff --git a/soh/soh/resource/type/Animation.h b/soh/soh/resource/type/Animation.h index e4ca4295f..9603e5477 100644 --- a/soh/soh/resource/type/Animation.h +++ b/soh/soh/resource/type/Animation.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource.h" +#include #include namespace SOH { diff --git a/soh/soh/resource/type/Array.cpp b/soh/soh/resource/type/Array.cpp index a4bbc0e5e..8a02faad7 100644 --- a/soh/soh/resource/type/Array.cpp +++ b/soh/soh/resource/type/Array.cpp @@ -1,5 +1,5 @@ #include "Array.h" -#include "graphic/Fast3D/lus_gbi.h" +#include namespace SOH { Array::Array() : Resource(std::shared_ptr()) { } diff --git a/soh/soh/resource/type/Array.h b/soh/soh/resource/type/Array.h index c7d15a22a..23d0b7e53 100644 --- a/soh/soh/resource/type/Array.h +++ b/soh/soh/resource/type/Array.h @@ -1,6 +1,6 @@ #pragma once -#include "resource/Resource.h" +#include namespace Fast { union F3DVtx; diff --git a/soh/soh/resource/type/AudioSample.h b/soh/soh/resource/type/AudioSample.h index 84e623781..eb29bc5bc 100644 --- a/soh/soh/resource/type/AudioSample.h +++ b/soh/soh/resource/type/AudioSample.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Resource.h" +#include #include namespace SOH { diff --git a/soh/soh/resource/type/AudioSequence.h b/soh/soh/resource/type/AudioSequence.h index b76645dee..90d5dd15e 100644 --- a/soh/soh/resource/type/AudioSequence.h +++ b/soh/soh/resource/type/AudioSequence.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Resource.h" +#include namespace SOH { diff --git a/soh/soh/resource/type/AudioSoundFont.h b/soh/soh/resource/type/AudioSoundFont.h index e387ede5f..0e07c0308 100644 --- a/soh/soh/resource/type/AudioSoundFont.h +++ b/soh/soh/resource/type/AudioSoundFont.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include #include "soh/resource/type/AudioSample.h" #include diff --git a/soh/soh/resource/type/Background.h b/soh/soh/resource/type/Background.h index 728e0207e..bd14e1509 100644 --- a/soh/soh/resource/type/Background.h +++ b/soh/soh/resource/type/Background.h @@ -1,6 +1,6 @@ #pragma once -#include "resource/Resource.h" +#include namespace SOH { class Background : public Ship::Resource { diff --git a/soh/soh/resource/type/CollisionHeader.h b/soh/soh/resource/type/CollisionHeader.h index 151437442..d6cd3c6fd 100644 --- a/soh/soh/resource/type/CollisionHeader.h +++ b/soh/soh/resource/type/CollisionHeader.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include #include #include "z64math.h" diff --git a/soh/soh/resource/type/Cutscene.h b/soh/soh/resource/type/Cutscene.h index e1f786ea5..59475d1cf 100644 --- a/soh/soh/resource/type/Cutscene.h +++ b/soh/soh/resource/type/Cutscene.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include namespace SOH { diff --git a/soh/soh/resource/type/Path.h b/soh/soh/resource/type/Path.h index baef6519c..42fc2946f 100644 --- a/soh/soh/resource/type/Path.h +++ b/soh/soh/resource/type/Path.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include #include #include "z64math.h" diff --git a/soh/soh/resource/type/PlayerAnimation.h b/soh/soh/resource/type/PlayerAnimation.h index db8e8ccf9..66cac19e0 100644 --- a/soh/soh/resource/type/PlayerAnimation.h +++ b/soh/soh/resource/type/PlayerAnimation.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include namespace SOH { class PlayerAnimation : public Ship::Resource { diff --git a/soh/soh/resource/type/Scene.h b/soh/soh/resource/type/Scene.h index 73fcd57a9..371890e76 100644 --- a/soh/soh/resource/type/Scene.h +++ b/soh/soh/resource/type/Scene.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "scenecommand/SceneCommand.h" #include diff --git a/soh/soh/resource/type/Skeleton.cpp b/soh/soh/resource/type/Skeleton.cpp index 027da1790..f2541dd06 100644 --- a/soh/soh/resource/type/Skeleton.cpp +++ b/soh/soh/resource/type/Skeleton.cpp @@ -1,4 +1,4 @@ -#include "resource/ResourceManager.h" +#include #include "Skeleton.h" #include "soh/OTRGlobals.h" #include "libultraship/libultraship.h" diff --git a/soh/soh/resource/type/Skeleton.h b/soh/soh/resource/type/Skeleton.h index 4d5dc0119..c3fd6f181 100644 --- a/soh/soh/resource/type/Skeleton.h +++ b/soh/soh/resource/type/Skeleton.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Resource.h" +#include #include "SkeletonLimb.h" #include diff --git a/soh/soh/resource/type/SkeletonLimb.h b/soh/soh/resource/type/SkeletonLimb.h index 5ee73b99a..84acd7741 100644 --- a/soh/soh/resource/type/SkeletonLimb.h +++ b/soh/soh/resource/type/SkeletonLimb.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource.h" +#include #include "libultraship/libultra.h" #include "z64math.h" diff --git a/soh/soh/resource/type/Text.h b/soh/soh/resource/type/Text.h index 535203716..ff921e731 100644 --- a/soh/soh/resource/type/Text.h +++ b/soh/soh/resource/type/Text.h @@ -2,7 +2,7 @@ #include #include -#include "Resource.h" +#include #include namespace SOH { diff --git a/soh/soh/resource/type/scenecommand/EndMarker.h b/soh/soh/resource/type/scenecommand/EndMarker.h index 37b06911d..5d3a0f7df 100644 --- a/soh/soh/resource/type/scenecommand/EndMarker.h +++ b/soh/soh/resource/type/scenecommand/EndMarker.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SceneCommand.h b/soh/soh/resource/type/scenecommand/SceneCommand.h index 99234b24a..1e71599dc 100644 --- a/soh/soh/resource/type/scenecommand/SceneCommand.h +++ b/soh/soh/resource/type/scenecommand/SceneCommand.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include namespace SOH { diff --git a/soh/soh/resource/type/scenecommand/SetActorList.h b/soh/soh/resource/type/scenecommand/SetActorList.h index d4ee3a902..b444aadd0 100644 --- a/soh/soh/resource/type/scenecommand/SetActorList.h +++ b/soh/soh/resource/type/scenecommand/SetActorList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" // #include #include "z64math.h" diff --git a/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h b/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h index 11dabd31f..38817d1a6 100644 --- a/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h +++ b/soh/soh/resource/type/scenecommand/SetAlternateHeaders.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include "soh/resource/type/Scene.h" #include "RomFile.h" diff --git a/soh/soh/resource/type/scenecommand/SetCameraSettings.h b/soh/soh/resource/type/scenecommand/SetCameraSettings.h index ad674d306..0cc03cfd5 100644 --- a/soh/soh/resource/type/scenecommand/SetCameraSettings.h +++ b/soh/soh/resource/type/scenecommand/SetCameraSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetCollisionHeader.h b/soh/soh/resource/type/scenecommand/SetCollisionHeader.h index b24673242..283a8bc0a 100644 --- a/soh/soh/resource/type/scenecommand/SetCollisionHeader.h +++ b/soh/soh/resource/type/scenecommand/SetCollisionHeader.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "soh/resource/type/scenecommand/SceneCommand.h" #include "soh/resource/type/CollisionHeader.h" // #include diff --git a/soh/soh/resource/type/scenecommand/SetCsCamera.h b/soh/soh/resource/type/scenecommand/SetCsCamera.h index fbd51e06c..42db07754 100644 --- a/soh/soh/resource/type/scenecommand/SetCsCamera.h +++ b/soh/soh/resource/type/scenecommand/SetCsCamera.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetCutscenes.h b/soh/soh/resource/type/scenecommand/SetCutscenes.h index 5ad28d4ae..0988b2027 100644 --- a/soh/soh/resource/type/scenecommand/SetCutscenes.h +++ b/soh/soh/resource/type/scenecommand/SetCutscenes.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "soh/resource/type/scenecommand/SceneCommand.h" #include "soh/resource/type/Cutscene.h" // #include diff --git a/soh/soh/resource/type/scenecommand/SetEchoSettings.h b/soh/soh/resource/type/scenecommand/SetEchoSettings.h index 2d17a879e..dfa0538a4 100644 --- a/soh/soh/resource/type/scenecommand/SetEchoSettings.h +++ b/soh/soh/resource/type/scenecommand/SetEchoSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetEntranceList.h b/soh/soh/resource/type/scenecommand/SetEntranceList.h index e41050c87..08fcf9fca 100644 --- a/soh/soh/resource/type/scenecommand/SetEntranceList.h +++ b/soh/soh/resource/type/scenecommand/SetEntranceList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetExitList.h b/soh/soh/resource/type/scenecommand/SetExitList.h index 56026075f..d9598c3cd 100644 --- a/soh/soh/resource/type/scenecommand/SetExitList.h +++ b/soh/soh/resource/type/scenecommand/SetExitList.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetLightList.h b/soh/soh/resource/type/scenecommand/SetLightList.h index d79a73aec..3a95a4f8f 100644 --- a/soh/soh/resource/type/scenecommand/SetLightList.h +++ b/soh/soh/resource/type/scenecommand/SetLightList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetLightingSettings.h b/soh/soh/resource/type/scenecommand/SetLightingSettings.h index cb2089517..ca9282225 100644 --- a/soh/soh/resource/type/scenecommand/SetLightingSettings.h +++ b/soh/soh/resource/type/scenecommand/SetLightingSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetMesh.h b/soh/soh/resource/type/scenecommand/SetMesh.h index d96661c43..1ab86530a 100644 --- a/soh/soh/resource/type/scenecommand/SetMesh.h +++ b/soh/soh/resource/type/scenecommand/SetMesh.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include "libultraship/libultra.h" #include "z64math.h" diff --git a/soh/soh/resource/type/scenecommand/SetObjectList.h b/soh/soh/resource/type/scenecommand/SetObjectList.h index 74081763a..5650f6d94 100644 --- a/soh/soh/resource/type/scenecommand/SetObjectList.h +++ b/soh/soh/resource/type/scenecommand/SetObjectList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetPathways.h b/soh/soh/resource/type/scenecommand/SetPathways.h index 377b5923d..ec2011367 100644 --- a/soh/soh/resource/type/scenecommand/SetPathways.h +++ b/soh/soh/resource/type/scenecommand/SetPathways.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" // #include #include "soh/resource/type/Path.h" diff --git a/soh/soh/resource/type/scenecommand/SetRoomBehavior.h b/soh/soh/resource/type/scenecommand/SetRoomBehavior.h index db59fa76b..8a1c2b832 100644 --- a/soh/soh/resource/type/scenecommand/SetRoomBehavior.h +++ b/soh/soh/resource/type/scenecommand/SetRoomBehavior.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetRoomList.h b/soh/soh/resource/type/scenecommand/SetRoomList.h index b60a75dbe..6fe6d33ff 100644 --- a/soh/soh/resource/type/scenecommand/SetRoomList.h +++ b/soh/soh/resource/type/scenecommand/SetRoomList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include "RomFile.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h b/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h index 7ed86ddc5..189e4ab3d 100644 --- a/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h +++ b/soh/soh/resource/type/scenecommand/SetSkyboxModifier.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h b/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h index d3d7b5a4c..cf3bbfbad 100644 --- a/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h +++ b/soh/soh/resource/type/scenecommand/SetSkyboxSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetSoundSettings.h b/soh/soh/resource/type/scenecommand/SetSoundSettings.h index 57e3beaae..ba180d823 100644 --- a/soh/soh/resource/type/scenecommand/SetSoundSettings.h +++ b/soh/soh/resource/type/scenecommand/SetSoundSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetSpecialObjects.h b/soh/soh/resource/type/scenecommand/SetSpecialObjects.h index 51a57c599..1e9e44e9f 100644 --- a/soh/soh/resource/type/scenecommand/SetSpecialObjects.h +++ b/soh/soh/resource/type/scenecommand/SetSpecialObjects.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetStartPositionList.h b/soh/soh/resource/type/scenecommand/SetStartPositionList.h index f2b097b0c..2b1ddce89 100644 --- a/soh/soh/resource/type/scenecommand/SetStartPositionList.h +++ b/soh/soh/resource/type/scenecommand/SetStartPositionList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include "soh/resource/type/scenecommand/SetActorList.h" // #include diff --git a/soh/soh/resource/type/scenecommand/SetTimeSettings.h b/soh/soh/resource/type/scenecommand/SetTimeSettings.h index ca95841e7..c5b63283b 100644 --- a/soh/soh/resource/type/scenecommand/SetTimeSettings.h +++ b/soh/soh/resource/type/scenecommand/SetTimeSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/resource/type/scenecommand/SetTransitionActorList.h b/soh/soh/resource/type/scenecommand/SetTransitionActorList.h index e740f128a..0b7149fa6 100644 --- a/soh/soh/resource/type/scenecommand/SetTransitionActorList.h +++ b/soh/soh/resource/type/scenecommand/SetTransitionActorList.h @@ -4,7 +4,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" // #include #include "z64math.h" diff --git a/soh/soh/resource/type/scenecommand/SetWindSettings.h b/soh/soh/resource/type/scenecommand/SetWindSettings.h index 755ad0d0d..87e0a3039 100644 --- a/soh/soh/resource/type/scenecommand/SetWindSettings.h +++ b/soh/soh/resource/type/scenecommand/SetWindSettings.h @@ -3,7 +3,7 @@ #include #include #include -#include "Resource.h" +#include #include "SceneCommand.h" #include diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index ea849af05..403541948 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -1,7 +1,7 @@ #include "OTRGlobals.h" #include #include "soh/resource/type/Scene.h" -#include +#include #include "global.h" #include "vt.h" #include "soh/resource/type/Text.h" diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 5055b969b..8864351b4 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -2,11 +2,11 @@ #include "ResourceManagerHelpers.h" #include #include "soh/resource/type/Scene.h" -#include +#include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "global.h" #include "vt.h" -#include +#include extern "C" void Play_InitScene(PlayState* play, s32 spawn); extern "C" void Play_InitEnvironment(PlayState* play, s16 skyboxId); diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp index 1baf6151d..d49367024 100644 --- a/soh/soh/z_scene_otr.cpp +++ b/soh/soh/z_scene_otr.cpp @@ -2,15 +2,15 @@ #include "ResourceManagerHelpers.h" #include #include "soh/resource/type/Scene.h" -#include +#include #include "global.h" #include "vt.h" #include "soh/resource/type/CollisionHeader.h" -#include +#include #include "soh/resource/type/Cutscene.h" #include "soh/resource/type/Path.h" #include "soh/resource/type/Text.h" -#include +#include #include #include #include "soh/resource/type/scenecommand/SetCameraSettings.h" diff --git a/soh/src/code/sys_ucode.c b/soh/src/code/sys_ucode.c index 39bbe3531..678c58c36 100644 --- a/soh/src/code/sys_ucode.c +++ b/soh/src/code/sys_ucode.c @@ -1,6 +1,6 @@ #include "global.h" -#include "public/bridge/gfxbridge.h" +#include UcodeHandlers sDefaultGSPUCodeText = ucode_f3dex2; // u64* sDefaultGSPUCodeData = gspF3DZEX2_NoN_PosLight_fifoDataStart; diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 493752555..172111b50 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -9,7 +9,7 @@ #include #include -#include "public/bridge/gfxbridge.h" +#include #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c index 3e79eb6ad..5b5665dab 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c @@ -8,7 +8,7 @@ #include "textures/icon_item_dungeon_static/icon_item_dungeon_static.h" #include "textures/icon_item_nes_static/icon_item_nes_static.h" -#include "public/bridge/gfxbridge.h" +#include void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) { static void* dungeonItemTexs[] = { From 52a8f6c2810df518dc853edefdacb829cf1863dd Mon Sep 17 00:00:00 2001 From: Malkierian Date: Thu, 9 Oct 2025 16:51:04 -0700 Subject: [PATCH 92/98] Program Execution Argument Extraction (#5807) * Add function to be able to feed specific path into to process programmatically, and setup drag and drop functionality. * Encapsulate dropped file functionality from Switch and Wii U. * Fix dropped file detection, and fix ShowYesNowBox return checking. --- soh/soh/Extractor/Extract.cpp | 28 ++++++++++++++++++++++++++++ soh/soh/Extractor/Extract.h | 1 + soh/soh/GbiWrap.cpp | 2 +- soh/soh/OTRGlobals.cpp | 27 ++++++++++++++++++++++++++- soh/soh/OTRGlobals.h | 2 +- soh/src/code/main.c | 7 +++---- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/soh/soh/Extractor/Extract.cpp b/soh/soh/Extractor/Extract.cpp index fecf9b741..558a3f74d 100644 --- a/soh/soh/Extractor/Extract.cpp +++ b/soh/soh/Extractor/Extract.cpp @@ -453,6 +453,34 @@ bool Extractor::ManuallySearchForRomMatchingType(RomSearchMode searchMode) { return true; } +bool Extractor::RunFileStandalone(std::string rom) { + if (std::filesystem::is_directory(rom)) { + return false; + } + auto file = std::filesystem::path(rom); + if ((file.extension() != ".n64") && (file.extension() != ".z64") && (file.extension() != ".v64")) { + return false; + } + SetRomInfo(rom); + + if (!ValidateRomSize()) { + return false; + } + std::ifstream inFile; + + inFile.open(rom, std::ios::in | std::ios::binary); + inFile.read((char*)mRomData.get(), mCurRomSize); + inFile.clear(); + inFile.close(); + BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize); + + if (!ValidateRom(true)) { + return false; + } + + return true; +} + bool Extractor::Run(std::string searchPath, RomSearchMode searchMode) { std::vector roms; std::ifstream inFile; diff --git a/soh/soh/Extractor/Extract.h b/soh/soh/Extractor/Extract.h index ae4fa740a..691233aba 100644 --- a/soh/soh/Extractor/Extract.h +++ b/soh/soh/Extractor/Extract.h @@ -59,6 +59,7 @@ class Extractor { static void ShowErrorBox(const char* title, const char* text); bool IsMasterQuest() const; + bool RunFileStandalone(std::string file); bool Run(std::string searchPath, RomSearchMode searchMode = RomSearchMode::Both); bool CallZapd(std::string installPath, std::string exportdir); const char* GetZapdStr(); diff --git a/soh/soh/GbiWrap.cpp b/soh/soh/GbiWrap.cpp index 0a26e9b18..1773c69c5 100644 --- a/soh/soh/GbiWrap.cpp +++ b/soh/soh/GbiWrap.cpp @@ -3,7 +3,7 @@ // OTRTODO - this is awful extern "C" { -void InitOTR(); +void InitOTR(int argc, char* argv[]); void Graph_ProcessFrame(void (*run_one_game_iter)(void)); void Graph_StartFrame(); void Graph_ProcessGfxCommands(Gfx* commands); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 3358d8585..342808e89 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1121,7 +1121,32 @@ void CheckAndCreateModFolder() { } } -extern "C" void InitOTR() { +extern "C" void InitOTR(int argc, char* argv[]) { +#if !defined(__SWITCH__) && !defined(__WIIU__) + if (argc > 1) { + for (int i = 1; i < argc; i++) { + std::string installPath = Ship::Context::GetAppBundlePath(); + Extractor extract; + if (extract.RunFileStandalone(argv[i])) { + bool doExtract = true; + std::string archive = (extract.IsMasterQuest() ? "oot-mq.o2r" : "oot.o2r"); + if (std::filesystem::exists(Ship::Context::GetAppBundlePath() + "/" + archive)) { + std::string msg = "Archive for current ROM, " + archive + ", already exists. Extract again?"; + doExtract = extract.ShowYesNoBox("Confirm Re-extract", msg.c_str()) == IDYES; + } + if (doExtract) { + extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName)); + } + } else { + std::string msg = "File " + std::string(argv[i]) + " is not a ROM or does not match supported ROMs."; + extract.ShowErrorBox("Incompatible File", msg.c_str()); + } + } + if (Extractor::ShowYesNoBox("Run Ship of Harkinian", "All files have been processed. Run SoH?") != IDYES) { + exit(0); + } + } +#endif OTRGlobals::Instance = new OTRGlobals(); #ifdef __SWITCH__ Ship::Switch::Init(Ship::PreInitPhase); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index b653e9edf..c7c5702a0 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -87,7 +87,7 @@ class OTRGlobals { #endif #ifndef __cplusplus -void InitOTR(void); +void InitOTR(int argc, char* argv[]); void DeinitOTR(void); void VanillaItemTable_Init(); void OTRAudio_Init(); diff --git a/soh/src/code/main.c b/soh/src/code/main.c index 769ecc026..558b30d2f 100644 --- a/soh/src/code/main.c +++ b/soh/src/code/main.c @@ -45,7 +45,7 @@ void Main_LogSystemHeap(void) { } #ifdef _WIN32 -int SDL_main(int argc, char** argv) { +int SDL_main(int argc, char* argv[]) { AllocConsole(); (void)freopen("CONIN$", "r", stdin); (void)freopen("CONOUT$", "w", stdout); @@ -57,11 +57,10 @@ int SDL_main(int argc, char** argv) { setlocale(LC_ALL, ".UTF8"); #else //_WIN32 -int main(int argc, char** argv) { +int main(int argc, char* argv[]) { #endif - GameConsole_Init(); - InitOTR(); + InitOTR(argc, argv); // TODO: Was moved to below InitOTR because it requires window to be setup. But will be late to catch crashes. CrashHandlerRegisterCallback(CrashHandler_PrintSohData); BootCommands_Init(); From f253d24cdc021953bc8ddab94642d4c1f4b3efe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 10 Oct 2025 17:25:41 +0000 Subject: [PATCH 93/98] Cheat: Disable Sandstorm (#5800) * Cheat: Disable Sandstorm Can also be considered an A11y feature, tho it'll always be hard with the muted colors, even if we added option to reduce fog * extern C? --- soh/soh/Enhancements/DisableSandstorm.cpp | 16 ++++++++++++++++ soh/soh/SohGui/SohMenuEnhancements.cpp | 3 +++ 2 files changed, 19 insertions(+) create mode 100644 soh/soh/Enhancements/DisableSandstorm.cpp diff --git a/soh/soh/Enhancements/DisableSandstorm.cpp b/soh/soh/Enhancements/DisableSandstorm.cpp new file mode 100644 index 000000000..a13fd4fb5 --- /dev/null +++ b/soh/soh/Enhancements/DisableSandstorm.cpp @@ -0,0 +1,16 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" + +extern "C" PlayState* gPlayState; + +void DisableSandstormAfterTransition(int16_t sceneNum) { + if (sceneNum == SCENE_HAUNTED_WASTELAND) { + gPlayState->envCtx.sandstormState = SANDSTORM_OFF; + } +} + +void RegisterDisableSandstorm() { + COND_HOOK(OnTransitionEnd, CVarGetInteger(CVAR_CHEAT("DisableSandstorm"), 0), DisableSandstormAfterTransition); +} + +static RegisterShipInitFunc initFunc(RegisterDisableSandstorm, { CVAR_CHEAT("DisableSandstorm") }); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 2f37291af..2b660fb94 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1746,6 +1746,9 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip( "Keese and Guay no longer target you and simply ignore you as if you were wearing the " "Skull Mask.")); + AddWidget(path, "Disable Haunted Wasteland Sandstorm", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_CHEAT("DisableSandstorm")) + .Options(CheckboxOptions().Tooltip("Disables sandstorm effect in Haunted Wasteland.")); AddWidget(path, "Glitch Aids", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Easy Frame Advancing with Pause", WIDGET_CVAR_CHECKBOX) From 8302c2322fe7cc1acb841be0dc10a2c9f6e4a09c Mon Sep 17 00:00:00 2001 From: Malkierian Date: Fri, 10 Oct 2025 13:26:06 -0700 Subject: [PATCH 94/98] Standardizes naming conventions for `ShipInit` and `MenuInit` registrations. (#5837) Fixes missing `static` keywords for two `ShipInit` registrations. --- soh/soh/Enhancements/BonkDamage.cpp | 2 +- soh/soh/Enhancements/BootToDebugWarpScreen.cpp | 5 ++--- soh/soh/Enhancements/Cheats/NoKeeseGuayTarget.cpp | 2 +- soh/soh/Enhancements/Cheats/NoRedeadFreeze.cpp | 2 +- soh/soh/Enhancements/ExtraModes/RupeeDash.cpp | 2 +- soh/soh/Enhancements/ExtraModes/ShadowTag.cpp | 2 +- soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp | 2 +- soh/soh/Enhancements/Presets/Presets.cpp | 2 +- soh/soh/Enhancements/QoL/DaytimeGS.cpp | 2 +- soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp | 2 +- .../Restorations/WideShutterDoorRanges.cpp | 3 +-- soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp | 2 +- soh/soh/Enhancements/audio/AudioEditor.cpp | 2 +- soh/soh/Enhancements/audio/AudioHooks.cpp | 2 +- soh/soh/Enhancements/controls/Mouse.cpp | 10 +++++----- soh/soh/Enhancements/controls/SohInputEditorWindow.cpp | 2 +- soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp | 6 +++--- soh/soh/Enhancements/cosmetics/TimeFlowFileSelect.cpp | 2 +- soh/soh/Enhancements/debugger/actorViewer.cpp | 2 +- soh/soh/Enhancements/debugger/valueViewer.cpp | 2 +- soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp | 4 ++-- soh/soh/Enhancements/randomizer/ShuffleCows.cpp | 4 ++-- soh/soh/Enhancements/randomizer/ShuffleCrates.cpp | 4 ++-- soh/soh/Enhancements/randomizer/ShuffleFairies.cpp | 2 +- .../Enhancements/randomizer/ShuffleFreestanding.cpp | 2 +- soh/soh/Enhancements/randomizer/ShuffleGrass.cpp | 2 +- soh/soh/Enhancements/randomizer/ShufflePots.cpp | 2 +- soh/soh/Enhancements/randomizer/ShuffleTrees.cpp | 2 +- .../randomizer/randomizer_check_tracker.cpp | 2 +- .../randomizer/randomizer_item_tracker.cpp | 2 +- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 4 ++-- soh/soh/ObjectExtension/ActorMaximumHealth.cpp | 2 +- soh/soh/SohGui/ResolutionEditor.cpp | 2 +- 33 files changed, 44 insertions(+), 46 deletions(-) diff --git a/soh/soh/Enhancements/BonkDamage.cpp b/soh/soh/Enhancements/BonkDamage.cpp index e11f46b78..c9e5e089a 100644 --- a/soh/soh/Enhancements/BonkDamage.cpp +++ b/soh/soh/Enhancements/BonkDamage.cpp @@ -48,4 +48,4 @@ void RegisterBonkDamage() { }); } -static RegisterShipInitFunc registerBonkDamage(RegisterBonkDamage, { CVAR_ENHANCEMENT("BonkDamageMult") }); +static RegisterShipInitFunc initFunc(RegisterBonkDamage, { CVAR_ENHANCEMENT("BonkDamageMult") }); diff --git a/soh/soh/Enhancements/BootToDebugWarpScreen.cpp b/soh/soh/Enhancements/BootToDebugWarpScreen.cpp index a2b8c6b60..dc0f1899b 100644 --- a/soh/soh/Enhancements/BootToDebugWarpScreen.cpp +++ b/soh/soh/Enhancements/BootToDebugWarpScreen.cpp @@ -42,6 +42,5 @@ void RegisterBootToDebugWarpScreen() { OnZTitleUpdateBootToDebugWarpScreen); } -static RegisterShipInitFunc initFunc_BootToDebugWarpScreen(RegisterBootToDebugWarpScreen, - { CVAR_DEBUG_ENABLED_NAME, - CVAR_BOOT_TO_DEBUG_WARP_SCREEN_NAME }); +static RegisterShipInitFunc initFunc(RegisterBootToDebugWarpScreen, + { CVAR_DEBUG_ENABLED_NAME, CVAR_BOOT_TO_DEBUG_WARP_SCREEN_NAME }); diff --git a/soh/soh/Enhancements/Cheats/NoKeeseGuayTarget.cpp b/soh/soh/Enhancements/Cheats/NoKeeseGuayTarget.cpp index 911f3cd25..3616191ca 100644 --- a/soh/soh/Enhancements/Cheats/NoKeeseGuayTarget.cpp +++ b/soh/soh/Enhancements/Cheats/NoKeeseGuayTarget.cpp @@ -20,4 +20,4 @@ void RegisterNoKeeseGuayTarget() { COND_VB_SHOULD(VB_GUAY_FORCE_FLY_AWAY, CVAR_NOKEESEGUAYTARGET_VALUE, { *should = true; }); } -static RegisterShipInitFunc initFunc_NoKeeseGuayTarget(RegisterNoKeeseGuayTarget, { CVAR_NOKEESEGUAYTARGET_NAME }); +static RegisterShipInitFunc initFunc(RegisterNoKeeseGuayTarget, { CVAR_NOKEESEGUAYTARGET_NAME }); diff --git a/soh/soh/Enhancements/Cheats/NoRedeadFreeze.cpp b/soh/soh/Enhancements/Cheats/NoRedeadFreeze.cpp index ccc406104..7ed245234 100644 --- a/soh/soh/Enhancements/Cheats/NoRedeadFreeze.cpp +++ b/soh/soh/Enhancements/Cheats/NoRedeadFreeze.cpp @@ -14,4 +14,4 @@ void RegisterNoRedeadFreeze() { COND_VB_SHOULD(VB_REDEAD_GIBDO_FREEZE_LINK, CVAR_NOREDEADFREEZE_VALUE, { *should = false; }); } -static RegisterShipInitFunc initFunc_NoRedeadFreeze(RegisterNoRedeadFreeze, { CVAR_NOREDEADFREEZE_NAME }); +static RegisterShipInitFunc initFunc(RegisterNoRedeadFreeze, { CVAR_NOREDEADFREEZE_NAME }); diff --git a/soh/soh/Enhancements/ExtraModes/RupeeDash.cpp b/soh/soh/Enhancements/ExtraModes/RupeeDash.cpp index 277868b20..20bdc16bc 100644 --- a/soh/soh/Enhancements/ExtraModes/RupeeDash.cpp +++ b/soh/soh/Enhancements/ExtraModes/RupeeDash.cpp @@ -40,4 +40,4 @@ void RegisterRupeeDash() { COND_HOOK(OnPlayerUpdate, CVAR_RUPEE_DASH_VALUE, UpdateRupeeDash); } -static RegisterShipInitFunc initFunc_RupeeDash(RegisterRupeeDash, { CVAR_RUPEE_DASH_NAME }); +static RegisterShipInitFunc initFunc(RegisterRupeeDash, { CVAR_RUPEE_DASH_NAME }); diff --git a/soh/soh/Enhancements/ExtraModes/ShadowTag.cpp b/soh/soh/Enhancements/ExtraModes/ShadowTag.cpp index dc85534c8..1b03b6c77 100644 --- a/soh/soh/Enhancements/ExtraModes/ShadowTag.cpp +++ b/soh/soh/Enhancements/ExtraModes/ShadowTag.cpp @@ -47,4 +47,4 @@ void RegisterShadowTag() { COND_HOOK(OnSceneInit, true, [](int16_t) { ResetShadowTagSpawnTimer(); }); } -static RegisterShipInitFunc initFunc_ShadowTag(RegisterShadowTag, { CVAR_SHADOW_TAG_NAME }); +static RegisterShipInitFunc initFunc(RegisterShadowTag, { CVAR_SHADOW_TAG_NAME }); diff --git a/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp b/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp index 9e9faafac..253e0abd2 100644 --- a/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp +++ b/soh/soh/Enhancements/Graphics/Disable2DBackgrounds.cpp @@ -158,4 +158,4 @@ void Register3DPreRenderedScenes() { }); } -static RegisterShipInitFunc PreRender3DInitFunc(Register3DPreRenderedScenes, { CVAR_NAME }); \ No newline at end of file +static RegisterShipInitFunc initFunc(Register3DPreRenderedScenes, { CVAR_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 75ff9aabd..058d5a2cd 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -445,4 +445,4 @@ void RegisterPresetsWidgets() { LoadPresets(); } -static RegisterMenuInitFunc initFunc(RegisterPresetsWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterPresetsWidgets); diff --git a/soh/soh/Enhancements/QoL/DaytimeGS.cpp b/soh/soh/Enhancements/QoL/DaytimeGS.cpp index fabf7457b..6d4474274 100644 --- a/soh/soh/Enhancements/QoL/DaytimeGS.cpp +++ b/soh/soh/Enhancements/QoL/DaytimeGS.cpp @@ -66,4 +66,4 @@ void RegisterDaytimeGoldSkultullas() { COND_HOOK(OnSceneSpawnActors, CVAR_DAYTIME_GS_VALUE, OnSpawnNighttimeGoldSkulltula); } -static RegisterShipInitFunc initFunc_DaytimeGoldSkulltulas(RegisterDaytimeGoldSkultullas, { CVAR_DAYTIME_GS_NAME }); +static RegisterShipInitFunc initFunc(RegisterDaytimeGoldSkultullas, { CVAR_DAYTIME_GS_NAME }); diff --git a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp index 760c3c903..525d30dc2 100644 --- a/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp +++ b/soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp @@ -69,4 +69,4 @@ void RegisterGraveHoleJumps() { ApplyGraveyardGeometryPatches(); } -static RegisterShipInitFunc initFunc_GraveHoleJumps(RegisterGraveHoleJumps, { CVAR_GRAVE_HOLE_NAME }); +static RegisterShipInitFunc initFunc(RegisterGraveHoleJumps, { CVAR_GRAVE_HOLE_NAME }); diff --git a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp index 78339a48b..7c56fab24 100644 --- a/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp +++ b/soh/soh/Enhancements/Restorations/WideShutterDoorRanges.cpp @@ -27,5 +27,4 @@ void RegisterWideShutterDoorRange() { }); } -static RegisterShipInitFunc initFunc_WideShutterDoorRange(RegisterWideShutterDoorRange, - { CVAR_WIDE_SHUTTER_DOOR_RANGE }); +static RegisterShipInitFunc initFunc(RegisterWideShutterDoorRange, { CVAR_WIDE_SHUTTER_DOOR_RANGE }); diff --git a/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp index 7ada74e98..2b8794978 100644 --- a/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp +++ b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp @@ -117,4 +117,4 @@ void CrawlSpeed_Register() { }); } -static RegisterShipInitFunc initSpeed(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME }); \ No newline at end of file +static RegisterShipInitFunc initFunc(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 5a7fb1414..be6acae73 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -894,4 +894,4 @@ void RegisterAudioWidgets() { SohGui::mSohMenu->AddSearchWidget({ lowerOctaves, "Enhancements", "Audio Editor", "Audio Options" }); } -static RegisterMenuInitFunc initAudioWidgets(RegisterAudioWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterAudioWidgets); diff --git a/soh/soh/Enhancements/audio/AudioHooks.cpp b/soh/soh/Enhancements/audio/AudioHooks.cpp index d2d6aa279..f035eb0d1 100644 --- a/soh/soh/Enhancements/audio/AudioHooks.cpp +++ b/soh/soh/Enhancements/audio/AudioHooks.cpp @@ -40,4 +40,4 @@ void RegisterAudioNotificationHooks() { COND_HOOK(OnSeqPlayerInit, CVAR_SEQOVERLAY_VALUE, NotifySequenceName); } -static RegisterShipInitFunc notifInitFunc(RegisterAudioNotificationHooks, { CVAR_SEQOVERLAY_NAME }); \ No newline at end of file +static RegisterShipInitFunc initFunc(RegisterAudioNotificationHooks, { CVAR_SEQOVERLAY_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/controls/Mouse.cpp b/soh/soh/Enhancements/controls/Mouse.cpp index 87af5168b..26e122504 100644 --- a/soh/soh/Enhancements/controls/Mouse.cpp +++ b/soh/soh/Enhancements/controls/Mouse.cpp @@ -148,9 +148,9 @@ void Mouse_RegisterHandleQuickspin() { REGISTER_VB_SHOULD(VB_SHOULD_QUICKSPIN, { Mouse_HandleQuickspin(should, va_arg(args, s8*), va_arg(args, s8*)); }); } -static RegisterShipInitFunc initFunc_shieldRecenter(Mouse_RegisterRecenterCursorOnShield, { CVAR_ENABLE_MOUSE_NAME }); -static RegisterShipInitFunc initFunc_firstPerson(Mouse_RegisterHandleFirstPerson, { CVAR_ENABLE_MOUSE_NAME }); -static RegisterShipInitFunc initFunc_quickspinCount(Mouse_RegisterUpdateQuickspinCount, { CVAR_ENABLE_MOUSE_NAME }); -static RegisterShipInitFunc initFunc_quickspin(Mouse_RegisterHandleQuickspin, { CVAR_ENABLE_MOUSE_NAME }); -static RegisterShipInitFunc initFunc_shieldMove(Mouse_RegisterHandleShield, { CVAR_ENABLE_MOUSE_NAME }); +static RegisterShipInitFunc registerShieldRecenter(Mouse_RegisterRecenterCursorOnShield, { CVAR_ENABLE_MOUSE_NAME }); +static RegisterShipInitFunc registerFirstPerson(Mouse_RegisterHandleFirstPerson, { CVAR_ENABLE_MOUSE_NAME }); +static RegisterShipInitFunc registerQuickspinCount(Mouse_RegisterUpdateQuickspinCount, { CVAR_ENABLE_MOUSE_NAME }); +static RegisterShipInitFunc registerQuickspin(Mouse_RegisterHandleQuickspin, { CVAR_ENABLE_MOUSE_NAME }); +static RegisterShipInitFunc registerShieldMove(Mouse_RegisterHandleShield, { CVAR_ENABLE_MOUSE_NAME }); } // extern "C" diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index bdfe6c1c1..208833d61 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -1969,4 +1969,4 @@ void RegisterInputEditorWidgets() { SohGui::mSohMenu->AddSearchWidget({ dpadText, "Settings", "Controls", "Dpad Controls" }); } -static RegisterMenuInitFunc initInputWidgets(RegisterInputEditorWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterInputEditorWidgets); diff --git a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp index 029284fa4..3ec872368 100644 --- a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp +++ b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp @@ -195,7 +195,7 @@ void RegisterCustomLogoTitle() { COND_HOOK(OnZTitleUpdate, true, OnZTitleUpdatePressButtonToSkip); } -static RegisterShipInitFunc initFuncAlways(RegisterCustomLogoTitle); +static RegisterShipInitFunc registerCustomLogo(RegisterCustomLogoTitle); // // // // // // // Bootsequence @@ -216,7 +216,7 @@ void RegisterCustomLogoTitleBootsequence() { COND_HOOK(OnZTitleUpdate, CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_FILESELECT, OnZTitleUpdateSkipToFileSelect); } -static RegisterShipInitFunc initFuncBootsequence(RegisterCustomLogoTitleBootsequence, { CVAR_BOOTSEQUENCE_NAME }); +static RegisterShipInitFunc registerTitleBootSequence(RegisterCustomLogoTitleBootsequence, { CVAR_BOOTSEQUENCE_NAME }); // // // // // // // Let it Snow @@ -230,4 +230,4 @@ void RegisterCustomLogoTitleLetItSnow() { shouldDrawIceOnSpinningLogo = CVAR_LETITSNOW_VALUE != CVAR_LETITSNOW_DEFAULT; } -static RegisterShipInitFunc initFuncLetItSnow(RegisterCustomLogoTitleLetItSnow, { CVAR_LETITSNOW_NAME }); +static RegisterShipInitFunc registerLetItSnow(RegisterCustomLogoTitleLetItSnow, { CVAR_LETITSNOW_NAME }); diff --git a/soh/soh/Enhancements/cosmetics/TimeFlowFileSelect.cpp b/soh/soh/Enhancements/cosmetics/TimeFlowFileSelect.cpp index d33f4f7e8..bd99ca1b1 100644 --- a/soh/soh/Enhancements/cosmetics/TimeFlowFileSelect.cpp +++ b/soh/soh/Enhancements/cosmetics/TimeFlowFileSelect.cpp @@ -17,4 +17,4 @@ void RegisterTimeFlowFileSelect() { COND_HOOK(OnFileChooseMain, CVAR_TIMEFLOWFILESELECT_VALUE, OnFileChooseMainTimeFlowFileSelect); } -static RegisterShipInitFunc initFunc_TimeFlowFileSelect(RegisterTimeFlowFileSelect, { CVAR_TIMEFLOWFILESELECT_NAME }); +static RegisterShipInitFunc initFunc(RegisterTimeFlowFileSelect, { CVAR_TIMEFLOWFILESELECT_NAME }); diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index d21d9449e..5792a4ec0 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -1228,4 +1228,4 @@ void ActorViewer_RegisterNameTagHooks() { [](void* actor) { ActorViewer_AddTagForActor(static_cast(actor)); }); } -RegisterShipInitFunc nametagInit(ActorViewer_RegisterNameTagHooks, { CVAR_ACTOR_NAME_TAGS_ENABLED_NAME }); +static RegisterShipInitFunc initFunc(ActorViewer_RegisterNameTagHooks, { CVAR_ACTOR_NAME_TAGS_ENABLED_NAME }); diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index 4544979cb..a4ab75e72 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -151,7 +151,7 @@ void RegisterValueViewerHooks() { COND_HOOK(OnGameFrameUpdate, CVAR_VALUE, []() { ValueViewer_SetupDraw(); }); } -RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME }); +static RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME }); void ValueViewerWindow::DrawElement() { ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index c5a8b8534..00c060cf9 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -99,7 +99,7 @@ void RegisterShuffleBeehives() { COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerUpdate); } -static RegisterShipInitFunc initFunc(RegisterShuffleBeehives, { "IS_RANDO" }); +static RegisterShipInitFunc registerShuffleBeehives(RegisterShuffleBeehives, { "IS_RANDO" }); void Rando::StaticData::RegisterBeehiveLocations() { static bool registered = false; @@ -143,4 +143,4 @@ void Rando::StaticData::RegisterBeehiveLocations() { } static ObjectExtension::Register RegisterBeehiveIdentity; -static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations); +static RegisterShipInitFunc registerBeehiveLocations(Rando::StaticData::RegisterBeehiveLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp index 17ae3a834..63fbd858c 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp @@ -58,7 +58,7 @@ void RegisterShuffleCows() { }); } -static RegisterShipInitFunc initFunc(RegisterShuffleCows, { "IS_RANDO" }); +static RegisterShipInitFunc registerShuffleCows(RegisterShuffleCows, { "IS_RANDO" }); void Rando::StaticData::RegisterCowLocations() { static bool registered = false; @@ -79,4 +79,4 @@ void Rando::StaticData::RegisterCowLocations() { // clang-format-on } -static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterCowLocations); +static RegisterShipInitFunc registerCowLocations(Rando::StaticData::RegisterCowLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index 6962b290d..007c12bc0 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -597,5 +597,5 @@ void Rando::StaticData::RegisterCrateLocations() { static ObjectExtension::Register RegisterCrateIdentity; static ObjectExtension::Register RegisterSmallCrateIdentity; -static RegisterShipInitFunc initFunc(RegisterShuffleCrates, { "IS_RANDO" }); -static RegisterShipInitFunc locFunc(Rando::StaticData::RegisterCrateLocations); +static RegisterShipInitFunc registerShuffleCrates(RegisterShuffleCrates, { "IS_RANDO" }); +static RegisterShipInitFunc registerCrateLocations(Rando::StaticData::RegisterCrateLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index 420ec0864..04e951e22 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -421,4 +421,4 @@ void Rando::StaticData::RegisterFairyLocations() { static ObjectExtension::Register RegisterFairyIdentity; static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" }); -static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations); +static RegisterShipInitFunc registerFairyLocations(Rando::StaticData::RegisterFairyLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp index 7291fdbef..dac291196 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp @@ -287,4 +287,4 @@ void Rando::StaticData::RegisterFreestandingLocations() { } static RegisterShipInitFunc registerShuffleFreestanding(RegisterShuffleFreestanding, { "IS_RANDO" }); -static RegisterShipInitFunc registerShuffleFreestandingLocations(Rando::StaticData::RegisterFreestandingLocations); +static RegisterShipInitFunc registerFreestandingLocations(Rando::StaticData::RegisterFreestandingLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index b11b06f3e..d82c3b393 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -530,4 +530,4 @@ void Rando::StaticData::RegisterGrassLocations() { static ObjectExtension::Register RegisterGrassIdentity; static RegisterShipInitFunc registerShuffleGrass(RegisterShuffleGrass, { "IS_RANDO" }); -static RegisterShipInitFunc registerShuffleGrassLocations(Rando::StaticData::RegisterGrassLocations); +static RegisterShipInitFunc registerGrassLocations(Rando::StaticData::RegisterGrassLocations); diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp index 869af92e4..815562578 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.cpp +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -661,4 +661,4 @@ void Rando::StaticData::RegisterPotLocations() { static ObjectExtension::Register RegisterPotIdentity; static RegisterShipInitFunc registerShufflePots(RegisterShufflePots, { "IS_RANDO" }); -static RegisterShipInitFunc registerShufflePotLocations(Rando::StaticData::RegisterPotLocations); +static RegisterShipInitFunc registerPotLocations(Rando::StaticData::RegisterPotLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index 418468e30..14cb9c7b1 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -262,4 +262,4 @@ void Rando::StaticData::RegisterTreeLocations() { static ObjectExtension::Register RegisterPotIdentity; static RegisterShipInitFunc registerShuffleTrees(RegisterShuffleTrees, { "IS_RANDO" }); -static RegisterShipInitFunc registerShuffleTreeLocations(Rando::StaticData::RegisterTreeLocations); +static RegisterShipInitFunc registerTreeLocations(Rando::StaticData::RegisterTreeLocations); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a907fdab4..e4d784664 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -2298,5 +2298,5 @@ void RegisterCheckTrackerWidgets() { }); } -static RegisterMenuInitFunc initCheckTrackerWidgets(RegisterCheckTrackerWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterCheckTrackerWidgets); } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index b3acc96d5..0288539d1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -2125,4 +2125,4 @@ void RegisterItemTrackerWidgets() { { hookshotIdentWidget, "Settings", "Controls", "Camera Controls", "longshot icon" }); } -static RegisterMenuInitFunc initItemTrackerWidgets(RegisterItemTrackerWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterItemTrackerWidgets); diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 793583698..8bcd19903 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -1471,5 +1471,5 @@ void RegisterSkipTimerDelay() { }); } -static RegisterShipInitFunc skipTimerDelay(RegisterSkipTimerDelay, - { CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" }); +static RegisterShipInitFunc initFunc(RegisterSkipTimerDelay, + { CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" }); diff --git a/soh/soh/ObjectExtension/ActorMaximumHealth.cpp b/soh/soh/ObjectExtension/ActorMaximumHealth.cpp index d8c74404b..a712b02d5 100644 --- a/soh/soh/ObjectExtension/ActorMaximumHealth.cpp +++ b/soh/soh/ObjectExtension/ActorMaximumHealth.cpp @@ -26,4 +26,4 @@ static void ActorMaximumHealth_Register() { }); } -static RegisterShipInitFunc actorMaximumHealthInit(ActorMaximumHealth_Register); +static RegisterShipInitFunc initFunc(ActorMaximumHealth_Register); diff --git a/soh/soh/SohGui/ResolutionEditor.cpp b/soh/soh/SohGui/ResolutionEditor.cpp index 232458d9a..8e84e5ab7 100644 --- a/soh/soh/SohGui/ResolutionEditor.cpp +++ b/soh/soh/SohGui/ResolutionEditor.cpp @@ -597,6 +597,6 @@ bool IsDroppingFrames() { } static RegisterMenuUpdateFunc updateFunc(UpdateResolutionVars, "Settings", "Graphics"); -static RegisterMenuInitFunc initFunc(RegisterResolutionWidgets); +static RegisterMenuInitFunc menuInitFunc(RegisterResolutionWidgets); } // namespace SohGui From 94b07aaa737f73cc388ed7ab524bdc91706efc93 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 13 Oct 2025 08:47:46 -0700 Subject: [PATCH 95/98] Pull in LUS audio API selection fix. (#5840) --- libultraship | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship b/libultraship index 2782e554d..a64f9f9d9 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 2782e554d961be13db8d862c6ab48839b82f30ee +Subproject commit a64f9f9d989ad0640736de6408fb7bc2456c7730 From e254c1f9084e441c9e1a6adf8f7a5401a6d548b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 13 Oct 2025 22:10:24 +0000 Subject: [PATCH 96/98] botw: water level toggle (#5710) amazingly the code already handles the flag being cleared to raise the water level, so only need to setup hooks for ocarina spot to toggle In MQ it's a diamond switch, so only need to turn it into a toggleable diamond switch --- .../vanilla-behavior/GIVanillaBehavior.h | 16 +++++++++ .../Enhancements/randomizer/hook_handlers.cpp | 34 +++++++++++++++++++ .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 15 ++++---- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index a0c2629d9..08d663c7e 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1362,6 +1362,22 @@ typedef enum { // - `*EnDs` VB_OFFER_BLUE_POTION, + // #### `result` + // ```c + // this->switchFlag >= 0 + // ``` + // #### `args` + // - `*EnOkarinaTag` + VB_OKARINA_TAG_COMPLETE, + + // #### `result` + // ```c + // (this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag)) + // ``` + // #### `args` + // - `*EnOkarinaTag` + VB_OKARINA_TAG_COMPLETED, + // #### `result` // ```c // CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index fa3aa4019..df950a35f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -48,6 +48,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Ds/z_en_ds.h" #include "src/overlays/actors/ovl_En_Gm/z_en_gm.h" #include "src/overlays/actors/ovl_En_Js/z_en_js.h" +#include "src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.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" @@ -1370,6 +1371,30 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should |= RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF; break; } + case VB_OKARINA_TAG_COMPLETE: { + if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) { + auto dungeon = + OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + if (dungeon->IsVanilla()) { + EnOkarinaTag* enOkarinaTag = va_arg(args, EnOkarinaTag*); + if (enOkarinaTag->switchFlag >= 0 && Flags_GetSwitch(gPlayState, enOkarinaTag->switchFlag)) { + Flags_UnsetSwitch(gPlayState, enOkarinaTag->switchFlag); + *should = false; + } + } + } + break; + } + case VB_OKARINA_TAG_COMPLETED: { + if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) { + auto dungeon = + OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + if (dungeon->IsVanilla()) { + *should = false; + } + } + break; + } case VB_GRANNY_SAY_INSUFFICIENT_RUPEES: { if (EnDs_RandoCanGetGrannyItem()) { *should = gSaveContext.rupees < @@ -2157,6 +2182,15 @@ void RandomizerOnActorInitHandler(void* actorRef) { return; } + // Turn MQ switch into toggle + if (actor->id == ACTOR_OBJ_SWITCH && gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL && (actor->params & 7) == 3) { + auto dungeon = + OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL); + if (dungeon->IsMQ()) { + actor->params |= 0x10; + } + } + // In ER, once Link has spawned we know the scene has loaded, so we can sanitize the last known entrance type if (actor->id == ACTOR_PLAYER && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { Grotto_SanitizeEntranceType(); diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 3dee59f27..cb59641fd 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -79,7 +79,8 @@ void EnOkarinaTag_Init(Actor* thisx, PlayState* play) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 当り?\t\t ☆☆☆☆☆ %d\n" VT_RST, this->unk_158); osSyncPrintf("\n\n"); - if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETED, + (this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag)), this)) { Actor_Kill(&this->actor); } else { switch (this->type) { @@ -113,7 +114,8 @@ void func_80ABEF2C(EnOkarinaTag* this, PlayState* play) { player = GET_PLAYER(play); this->unk_15A++; - if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETED, + (this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag)), this)) { this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; } else { if ((this->ocarinaSong != 6) || (gSaveContext.scarecrowSpawnSongSet)) { @@ -148,7 +150,7 @@ void func_80ABF0CC(EnOkarinaTag* this, PlayState* play) { this->actionFunc = func_80ABEF2C; } else { if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (this->switchFlag >= 0) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETE, this->switchFlag >= 0, this)) { Flags_SetSwitch(play, this->switchFlag); } if (play->sceneNum == SCENE_WATER_TEMPLE) { @@ -167,7 +169,7 @@ void func_80ABF0CC(EnOkarinaTag* this, PlayState* play) { (play->msgCtx.ocarinaMode == OCARINA_MODE_07) || (play->msgCtx.ocarinaMode == OCARINA_MODE_08) || (play->msgCtx.ocarinaMode == OCARINA_MODE_09) || (play->msgCtx.ocarinaMode == OCARINA_MODE_0A) || (play->msgCtx.ocarinaMode == OCARINA_MODE_0D)) { - if (this->switchFlag >= 0) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETE, this->switchFlag >= 0, this)) { Flags_SetSwitch(play, this->switchFlag); } play->msgCtx.ocarinaMode = OCARINA_MODE_04; @@ -190,7 +192,8 @@ void func_80ABF28C(EnOkarinaTag* this, PlayState* play) { this->unk_15A++; if ((this->ocarinaSong != 6) || (gSaveContext.scarecrowSpawnSongSet)) { - if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETED, + (this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag)), this)) { this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; } else if (((this->type != 4) || GameInteractor_Should(VB_BE_ELIGIBLE_TO_OPEN_DOT, @@ -237,7 +240,7 @@ void func_80ABF4C8(EnOkarinaTag* this, PlayState* play) { this->actionFunc = func_80ABF28C; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); - if (this->switchFlag >= 0) { + if (GameInteractor_Should(VB_OKARINA_TAG_COMPLETE, this->switchFlag >= 0, this)) { Flags_SetSwitch(play, this->switchFlag); } switch (this->type) { From 73f3427ced6e29cccc31eb369e7b0cd7cd5382e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 13 Oct 2025 22:10:51 +0000 Subject: [PATCH 97/98] rando: remove vanilla (#5805) --- .../Enhancements/randomizer/3drando/fill.cpp | 3 +- .../randomizer/3drando/playthrough.cpp | 10 +- soh/soh/Enhancements/randomizer/context.cpp | 3 +- .../randomizer/option_descriptions.cpp | 6 +- .../Enhancements/randomizer/randomizer.cpp | 20 +- .../Enhancements/randomizer/randomizerTypes.h | 1 - .../randomizer/randomizer_check_tracker.cpp | 2 +- soh/soh/Enhancements/randomizer/settings.cpp | 287 ++++++++---------- 8 files changed, 136 insertions(+), 196 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index fe0ab514b..3204ace65 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -973,8 +973,7 @@ static void RandomizeDungeonRewards() { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA) || - ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS) + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS) .Is(RO_DUNGEON_REWARDS_VANILLA)) { // Place dungeon rewards in vanilla locations for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) { ctx->GetItemLocation(loc)->PlaceVanillaItem(); diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 1e4a3db38..7e73d2906 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -65,13 +65,9 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, Random_Init(finalHash); ctx->SetHash(std::to_string(finalHash)); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { - VanillaFill(); // Just place items in their vanilla locations - } else { // Fill locations with logic - int ret = Fill(); - if (ret < 0) { - return ret; - } + int ret = Fill(); + if (ret < 0) { + return ret; } GenerateHash(); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 05e459198..9bb7247d1 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -124,8 +124,7 @@ void Context::PlaceItemInLocation(const RandomizerCheck locKey, const Randomizer SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + StaticData::GetLocation(locKey)->GetName() + "\n"); - if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS) || - mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) { + if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS)) { StaticData::RetrieveItem(item).ApplyEffect(); } diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 4a981fccb..ce9b261d6 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -754,11 +754,7 @@ void Settings::CreateOptionDescriptions() { "Glitchless - No glitches are required, but may require some minor tricks. Additional tricks may be enabled " "and disabled below.\n" "\n" - //"Glitched - Glitches may be required to beat the game. You can disable and enable glitches below.\n" - //"\n" - "No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT.\n" - "\n" - "Vanilla - Places all items and dungeon rewards in their vanilla locations."; + "No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT."; mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE] = "When this options is enabled, the randomizer will " "guarantee that every item is obtainable and every " "location is reachable. When disabled, only " diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 6d0047ec9..918a0701a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4009,32 +4009,24 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::BeginTabItem("Items")) { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == - RO_LOGIC_VANILLA); if (mSettings->GetOptionGroup(RSG_ITEMS_IMGUI_TABLE).RenderImGui()) { mNeedsUpdate = true; } - ImGui::EndDisabled(); ImGui::PopStyleVar(1); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Gameplay")) { - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == - RO_LOGIC_VANILLA); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); if (mSettings->GetOptionGroup(RSG_GAMEPLAY_IMGUI_TABLE).RenderImGui()) { mNeedsUpdate = true; } - ImGui::EndDisabled(); ImGui::PopStyleVar(1); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Locations")) { - ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == - RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); if (!locationsTabOpen) { locationsTabOpen = true; @@ -4208,19 +4200,11 @@ void RandomizerSettingsWindow::DrawElement() { mNeedsUpdate = true; } } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA) { - ImGui::SameLine(); - ImGui::TextColored( - ImVec4(1.0f, 0.0f, 0.0f, 1.0f), - "Heads up! This will disable all rando settings except for entrance shuffle and starter items"); - } ImGui::PopItemWidth(); ImGui::EndTable(); } - ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == - RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings); // Tricks static std::unordered_map areaTreeDisabled{ diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 85a77416e..c3adadcec 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -6522,7 +6522,6 @@ typedef enum { typedef enum { RO_LOGIC_GLITCHLESS, RO_LOGIC_NO_LOGIC, - RO_LOGIC_VANILLA, } RandoOptionLogic; // Damage Multiplier diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index e4d784664..6a468ff64 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1554,7 +1554,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { if (loc->GetRCType() == RCTYPE_SHOP) { auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); } - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { + if (IS_RANDO) { return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them (loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 8efd6c1f9..7f67f946b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -332,7 +332,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_STARTING_SKULLTULA_TOKEN, "Gold Skulltula Tokens", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), "", WidgetType::Slider); OPT_U8(RSK_STARTING_HEARTS, "Starting Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), "", WidgetType::Slider, 2); // TODO: Remainder of Starting Items - OPT_U8(RSK_LOGIC_RULES, "Logic", {"Glitchless", "No Logic", "Vanilla"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WidgetType::Combobox, RO_LOGIC_GLITCHLESS); + OPT_U8(RSK_LOGIC_RULES, "Logic", {"Glitchless", "No Logic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WidgetType::Combobox, RO_LOGIC_GLITCHLESS); OPT_BOOL(RSK_ALL_LOCATIONS_REACHABLE, "All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WidgetType::Checkbox, RO_GENERIC_ON); OPT_BOOL(RSK_SKULLS_SUNS_SONG, "Night Skulltula's Expect Sun's Song", CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), mOptionDescriptions[RSK_SKULLS_SUNS_SONG]); OPT_U8(RSK_DAMAGE_MULTIPLIER, "Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT); @@ -1845,158 +1845,134 @@ void Settings::UpdateOptionProperties() { mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Hide(); mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Hide(); mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Hide(); - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA) { - mOptionGroups[RSG_AREA_ACCESS_IMGUI].Disable(); - mOptions[RSK_STARTING_AGE].Disable(""); - mOptions[RSK_GERUDO_FORTRESS].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE].Disable(""); - mOptions[RSK_BRIDGE_OPTIONS].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Disable(""); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Disable(""); - mOptions[RSK_GANONS_TRIALS].Disable(""); - mOptions[RSK_TRIAL_COUNT].Disable(""); - mOptions[RSK_TRIFORCE_HUNT].Disable(""); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Disable(""); - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Disable(""); - mOptionGroups[RSG_ITEMS_IMGUI_TABLE].Disable(); - mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE].Disable(); - mOptions[RSK_LINKS_POCKET].Disable(""); - mOptions[RSK_STARTING_OCARINA].Disable(""); + mOptionGroups[RSG_AREA_ACCESS_IMGUI].Enable(); + // Starting Age - Disabled when Forest is set to Closed or under very specific conditions + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_CLOSED) == RO_DOOROFTIME_CLOSED && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_OFF) == + RO_GENERIC_OFF) /* closed door of time with ocarina shuffle off */ { + mOptions[RSK_STARTING_AGE].Disable("This option is disabled due to other options making the game unbeatable."); } else { - mOptionGroups[RSG_AREA_ACCESS_IMGUI].Enable(); - // Starting Age - Disabled when Forest is set to Closed or under very specific conditions - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_CLOSED) == RO_DOOROFTIME_CLOSED && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_OFF) == - RO_GENERIC_OFF) /* closed door of time with ocarina shuffle off */ { - mOptions[RSK_STARTING_AGE].Disable( - "This option is disabled due to other options making the game unbeatable."); - } else { - mOptions[RSK_STARTING_AGE].Enable(); - } - mOptions[RSK_GERUDO_FORTRESS].Enable(); - mOptions[RSK_RAINBOW_BRIDGE].Enable(); - mOptions[RSK_BRIDGE_OPTIONS].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Enable(); - const uint8_t bridgeOpt = - CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_VANILLA)) { - case RO_BRIDGE_STONES: - // Show Bridge Options and Stone Count slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 4) { - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 4)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 5) { - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 3)); - } - } - break; - case RO_BRIDGE_MEDALLIONS: - // Show Bridge Options and Medallion Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 7) { - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 8) { - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6)); - } - } - break; - case RO_BRIDGE_DUNGEON_REWARDS: - // Show Bridge Options and Dungeon Reward Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 10) { - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 10)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 11) { - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } - break; - case RO_BRIDGE_DUNGEONS: - // Show Bridge Options and Dungeon Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 9) { - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 10) { - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8)); - } - } - break; - case RO_BRIDGE_TOKENS: - // Show token count slider (not bridge options) - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Hide(); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Unhide(); - break; - default: - break; - } - mOptions[RSK_GANONS_TRIALS].Enable(); - mOptions[RSK_TRIAL_COUNT].Enable(); - // Only show the trial count slider if Trials is set to Set Number - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER) == - RO_GANONS_TRIALS_SET_NUMBER) { - mOptions[RSK_GANONS_TRIALS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_TRIAL_COUNT].Unhide(); - } else { - mOptions[RSK_GANONS_TRIALS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_TRIAL_COUNT].Hide(); - } - mOptions[RSK_TRIFORCE_HUNT].Enable(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Enable(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Enable(); - // Remove the pieces required/total sliders and add a separator after Tirforce Hunt if Triforce Hunt is off - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide(); - mOptions[RSK_TRIFORCE_HUNT].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - } else { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Unhide(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Unhide(); - mOptions[RSK_TRIFORCE_HUNT].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - } - // Update triforce pieces required to be capped at the current value for pieces total. - const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 30); - if (mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].GetOptionCount() != triforceTotal + 1) { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].ChangeOptions(NumOpts(1, triforceTotal + 1)); - } - mOptionGroups[RSG_ITEMS_IMGUI_TABLE].Enable(); - mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE].Enable(); - // Link's Pocket - Disabled when Dungeon Rewards are shuffled to End of Dungeon - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == - RO_DUNGEON_REWARDS_END_OF_DUNGEON) { - mOptions[RSK_LINKS_POCKET].Disable( - "This option is disabled because \"Dungeon Rewards\" are shuffled to \"End of Dungeons\"."); - } else { - mOptions[RSK_LINKS_POCKET].Enable(); - } - mOptions[RSK_STARTING_OCARINA].Enable(); + mOptions[RSK_STARTING_AGE].Enable(); } + mOptions[RSK_GERUDO_FORTRESS].Enable(); + mOptions[RSK_RAINBOW_BRIDGE].Enable(); + mOptions[RSK_BRIDGE_OPTIONS].Enable(); + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Enable(); + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Enable(); + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Enable(); + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Enable(); + mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Enable(); + const uint8_t bridgeOpt = CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD); + switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_VANILLA)) { + case RO_BRIDGE_STONES: + // Show Bridge Options and Stone Count slider + mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_BRIDGE_OPTIONS].Unhide(); + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Unhide(); + if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { + if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 4) { + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 4)); + } + } else { + if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 5) { + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 3)); + } + } + break; + case RO_BRIDGE_MEDALLIONS: + // Show Bridge Options and Medallion Count Slider + mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_BRIDGE_OPTIONS].Unhide(); + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Unhide(); + if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { + if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 7) { + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7)); + } + } else { + if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 8) { + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6)); + } + } + break; + case RO_BRIDGE_DUNGEON_REWARDS: + // Show Bridge Options and Dungeon Reward Count Slider + mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_BRIDGE_OPTIONS].Unhide(); + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Unhide(); + if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { + if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 10) { + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 10)); + } + } else { + if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 11) { + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 9)); + } + } + break; + case RO_BRIDGE_DUNGEONS: + // Show Bridge Options and Dungeon Count Slider + mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_BRIDGE_OPTIONS].Unhide(); + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Unhide(); + if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { + if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 9) { + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9)); + } + } else { + if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 10) { + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8)); + } + } + break; + case RO_BRIDGE_TOKENS: + // Show token count slider (not bridge options) + mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_BRIDGE_OPTIONS].Hide(); + mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Unhide(); + break; + default: + break; + } + mOptions[RSK_GANONS_TRIALS].Enable(); + mOptions[RSK_TRIAL_COUNT].Enable(); + // Only show the trial count slider if Trials is set to Set Number + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER) == + RO_GANONS_TRIALS_SET_NUMBER) { + mOptions[RSK_GANONS_TRIALS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_TRIAL_COUNT].Unhide(); + } else { + mOptions[RSK_GANONS_TRIALS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_TRIAL_COUNT].Hide(); + } + mOptions[RSK_TRIFORCE_HUNT].Enable(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Enable(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Enable(); + // Remove the pieces required/total sliders and add a separator after Tirforce Hunt if Triforce Hunt is off + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { + mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide(); + mOptions[RSK_TRIFORCE_HUNT].AddFlag(IMFLAG_SEPARATOR_BOTTOM); + } else { + mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Unhide(); + mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Unhide(); + mOptions[RSK_TRIFORCE_HUNT].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + } + // Update triforce pieces required to be capped at the current value for pieces total. + const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 30); + if (mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].GetOptionCount() != triforceTotal + 1) { + mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].ChangeOptions(NumOpts(1, triforceTotal + 1)); + } + mOptionGroups[RSG_ITEMS_IMGUI_TABLE].Enable(); + mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE].Enable(); + // Link's Pocket - Disabled when Dungeon Rewards are shuffled to End of Dungeon + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == + RO_DUNGEON_REWARDS_END_OF_DUNGEON) { + mOptions[RSK_LINKS_POCKET].Disable( + "This option is disabled because \"Dungeon Rewards\" are shuffled to \"End of Dungeons\"."); + } else { + mOptions[RSK_LINKS_POCKET].Enable(); + } + mOptions[RSK_STARTING_OCARINA].Enable(); // Don't show any MQ options if both quests aren't available if (!(OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal())) { @@ -2913,15 +2889,6 @@ void Context::FinalizeSettings(const std::set& excludedLocation mLACSCondition = RO_LACS_VANILLA; } - if (mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) { - for (OptionValue* setting : VanillaLogicDefaults) { - // setting->SetDelayedOption(); - setting->Set(0); - } - // mOptions[RSK_KEYSANITY].SetDelayedOption(); - mOptions[RSK_KEYSANITY].Set(3); - } - if (!mOptions[RSK_SHUFFLE_WARP_SONGS]) { mOptions[RSK_WARP_SONG_HINTS].Set(RO_GENERIC_OFF); } From 56ab4c51fd26029934acc5fedeb1491b81e2d8a3 Mon Sep 17 00:00:00 2001 From: Cameron <105471409+keraion@users.noreply.github.com> Date: Mon, 13 Oct 2025 18:11:55 -0400 Subject: [PATCH 98/98] Rando: Split fairysanity into distinct options (#5726) * Split Fairysanity into groups * Split fairy registration per type * fix song fairy shuffle locations * Change "Song Fairies" to "Fairy Spots" * Update preset settings * clang format * simplify `shouldRegister` logic --- .../custom/presets/Rando Hell Mode.json | 5 +- .../randomizer/3drando/item_pool.cpp | 41 +- .../randomizer/ShuffleFairies.cpp | 440 +++++++++--------- soh/soh/Enhancements/randomizer/context.cpp | 10 +- soh/soh/Enhancements/randomizer/location.cpp | 36 +- soh/soh/Enhancements/randomizer/location.h | 18 +- .../Enhancements/randomizer/location_list.cpp | 34 +- .../randomizer/option_descriptions.cpp | 10 +- .../Enhancements/randomizer/randomizerTypes.h | 10 +- .../randomizer/randomizer_check_objects.cpp | 10 +- .../randomizer/randomizer_check_tracker.cpp | 26 +- soh/soh/Enhancements/randomizer/settings.cpp | 15 +- soh/soh/Enhancements/randomizer/static_data.h | 5 +- 13 files changed, 410 insertions(+), 250 deletions(-) diff --git a/soh/assets/custom/presets/Rando Hell Mode.json b/soh/assets/custom/presets/Rando Hell Mode.json index d42727127..cdcceb451 100644 --- a/soh/assets/custom/presets/Rando Hell Mode.json +++ b/soh/assets/custom/presets/Rando Hell Mode.json @@ -34,6 +34,7 @@ "ShopsanityPrices": 2, "Shuffle100GSReward": 1, "ShuffleAdultTrade": 1, + "ShuffleBeanFairies": 1, "ShuffleBeehives": 1, "ShuffleBossEntrances": 2, "ShuffleBossSouls": 2, @@ -43,8 +44,9 @@ "ShuffleDekuNutBag": 1, "ShuffleDekuStickBag": 1, "ShuffleDungeonsEntrances": 2, - "ShuffleFairies": 1, + "ShuffleFairySpots": 1, "ShuffleFishingPole": 1, + "ShuffleFountainFairies": 1, "ShuffleFreestanding": 3, "ShuffleFrogSongRupees": 1, "ShuffleGanonBossKey": 9, @@ -63,6 +65,7 @@ "ShufflePots": 3, "ShuffleScrubs": 2, "ShuffleSongs": 2, + "ShuffleStoneFairies": 1, "ShuffleSwim": 1, "ShuffleTokens": 3, "ShuffleWarpSongs": 1, diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index cd179676d..e8cab933f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -996,13 +996,44 @@ void GenerateItemPool() { AddItemsToPool(ItemPool, shopsanityRupees); // Shopsanity gets extra large rupees } - // Shuffle Fairies - if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) { - for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) { + // Shuffle Fountain Fairies + if (ctx->GetOption(RSK_SHUFFLE_FOUNTAIN_FAIRIES)) { + for (auto rc : Rando::StaticData::GetFountainFairyLocations()) { AddItemToMainPool(GetJunkItem()); } - // 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple - int extra = 13; + // 8 extra for Ganon's Castle + int extra = 8; + for (int i = 0; i < extra; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + + // Shuffle Gossip Stone Fairies + if (ctx->GetOption(RSK_SHUFFLE_STONE_FAIRIES)) { + for (auto rc : Rando::StaticData::GetStoneFairyLocations()) { + AddItemToMainPool(GetJunkItem()); + } + // 2 Dodongo's Cavern Gossip Stone + int extra = 2; + for (int i = 0; i < extra; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + + // Shuffle Bean Fairies + if (ctx->GetOption(RSK_SHUFFLE_BEAN_FAIRIES)) { + for (auto rc : Rando::StaticData::GetBeanFairyLocations()) { + AddItemToMainPool(GetJunkItem()); + } + } + + // Shuffle Song Fairies + if (ctx->GetOption(RSK_SHUFFLE_SONG_FAIRIES)) { + for (auto rc : Rando::StaticData::GetSongFairyLocations()) { + AddItemToMainPool(GetJunkItem()); + } + // 3 Shadow Temple + int extra = 3; extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2; extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3; extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1; diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index 04e951e22..75717f8e9 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -89,7 +89,11 @@ static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType f } void RegisterShuffleFairies() { - bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES); + bool shouldRegisterFountain = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FOUNTAIN_FAIRIES); + bool shouldRegisterStone = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_STONE_FAIRIES); + bool shouldRegisterBean = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BEAN_FAIRIES); + bool shouldRegisterSong = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SONG_FAIRIES); + bool shouldRegister = shouldRegisterFountain || shouldRegisterStone || shouldRegisterBean || shouldRegisterSong; // Grant item when picking up fairy. COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, { @@ -106,7 +110,7 @@ void RegisterShuffleFairies() { }); // Spawn fairies in fairy fountains - COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegister, { + COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegisterFountain, { Actor* actor = va_arg(args, Actor*); bool fairySpawned = false; s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0; @@ -122,7 +126,7 @@ void RegisterShuffleFairies() { }); // Spawn 3 fairies when playing Song of Storms next to a planted bean - COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegister, { + COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegisterBean, { ObjBean* objBean = va_arg(args, ObjBean*); bool fairySpawned = false; for (s16 index = 0; index < 3; index++) { @@ -138,7 +142,7 @@ void RegisterShuffleFairies() { }); // Spawn a fairy from a ShotSun when playing the right song near it - COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegister, { + COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegisterSong, { ShotSun* shotSun = va_arg(args, ShotSun*); if (SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, shotSun->actor.world.pos.z, TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z), FAIRY_HEAL_BIG)) { @@ -147,7 +151,7 @@ void RegisterShuffleFairies() { }); // Handle playing both misc songs and song of storms in front of a gossip stone. - COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegister, { + COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegisterStone, { EnGs* gossipStone = va_arg(args, EnGs*); FairyType fairyType = FAIRY_HEAL; @@ -196,225 +200,225 @@ void Rando::StaticData::RegisterFairyLocations() { return; registered = true; // clang-format off - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Fairy Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1801, "Fairy Grotto Fairy 2", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1802, "Fairy Grotto Fairy 3", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1803, "Fairy Grotto Fairy 4", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1804, "Fairy Grotto Fairy 5", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1805, "Fairy Grotto Fairy 6", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1806, "Fairy Grotto Fairy 7", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7)); - locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1807, "Fairy Grotto Fairy 8", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0300, "Fairy Grotto Fairy 1", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0301, "Fairy Grotto Fairy 2", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0302, "Fairy Grotto Fairy 3", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0303, "Fairy Grotto Fairy 4", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0304, "Fairy Grotto Fairy 5", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0305, "Fairy Grotto Fairy 6", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0306, "Fairy Grotto Fairy 7", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7)); - locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0307, "Fairy Grotto Fairy 8", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F00, "Fairy Grotto Fairy 1", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_1)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F01, "Fairy Grotto Fairy 2", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_2)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F02, "Fairy Grotto Fairy 3", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_3)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F03, "Fairy Grotto Fairy 4", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_4)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F04, "Fairy Grotto Fairy 5", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_5)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F05, "Fairy Grotto Fairy 6", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_6)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F06, "Fairy Grotto Fairy 7", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_7)); - locationTable[RC_HF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F07, "Fairy Grotto Fairy 8", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_8)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C00, "Fairy Grotto Fairy 1", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C01, "Fairy Grotto Fairy 2", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C02, "Fairy Grotto Fairy 3", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C03, "Fairy Grotto Fairy 4", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C04, "Fairy Grotto Fairy 5", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C05, "Fairy Grotto Fairy 6", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C06, "Fairy Grotto Fairy 7", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7)); - locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C07, "Fairy Grotto Fairy 8", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D00, "Fairy Grotto Fairy 1", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_1)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D01, "Fairy Grotto Fairy 2", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_2)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D02, "Fairy Grotto Fairy 3", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_3)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D03, "Fairy Grotto Fairy 4", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_4)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D04, "Fairy Grotto Fairy 5", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_5)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D05, "Fairy Grotto Fairy 6", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_6)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D06, "Fairy Grotto Fairy 7", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_7)); - locationTable[RC_GF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D07, "Fairy Grotto Fairy 8", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Fairy Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1801, "Fairy Grotto Fairy 2", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1802, "Fairy Grotto Fairy 3", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1803, "Fairy Grotto Fairy 4", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1804, "Fairy Grotto Fairy 5", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1805, "Fairy Grotto Fairy 6", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1806, "Fairy Grotto Fairy 7", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1807, "Fairy Grotto Fairy 8", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0300, "Fairy Grotto Fairy 1", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0301, "Fairy Grotto Fairy 2", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0302, "Fairy Grotto Fairy 3", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0303, "Fairy Grotto Fairy 4", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0304, "Fairy Grotto Fairy 5", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0305, "Fairy Grotto Fairy 6", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0306, "Fairy Grotto Fairy 7", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0307, "Fairy Grotto Fairy 8", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F00, "Fairy Grotto Fairy 1", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F01, "Fairy Grotto Fairy 2", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F02, "Fairy Grotto Fairy 3", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F03, "Fairy Grotto Fairy 4", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F04, "Fairy Grotto Fairy 5", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F05, "Fairy Grotto Fairy 6", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F06, "Fairy Grotto Fairy 7", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F07, "Fairy Grotto Fairy 8", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C00, "Fairy Grotto Fairy 1", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C01, "Fairy Grotto Fairy 2", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C02, "Fairy Grotto Fairy 3", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C03, "Fairy Grotto Fairy 4", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C04, "Fairy Grotto Fairy 5", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C05, "Fairy Grotto Fairy 6", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C06, "Fairy Grotto Fairy 7", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C07, "Fairy Grotto Fairy 8", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D00, "Fairy Grotto Fairy 1", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D01, "Fairy Grotto Fairy 2", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D02, "Fairy Grotto Fairy 3", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D03, "Fairy Grotto Fairy 4", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D04, "Fairy Grotto Fairy 5", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D05, "Fairy Grotto Fairy 6", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D06, "Fairy Grotto Fairy 7", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D07, "Fairy Grotto Fairy 8", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_8)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x00, "Shield Grave Fairy 1", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x01, "Shield Grave Fairy 2", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x02, "Shield Grave Fairy 3", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x03, "Shield Grave Fairy 4", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x04, "Shield Grave Fairy 5", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x05, "Shield Grave Fairy 6", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x06, "Shield Grave Fairy 7", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7)); - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x07, "Shield Grave Fairy 8", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7)); - locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "MQ Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "MQ Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "MQ Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "MQ Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7)); - locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_1] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x00, "Oasis Fairy 1", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_1)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_2] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x01, "Oasis Fairy 2", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_2)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_3] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x02, "Oasis Fairy 3", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_3)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_4] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x03, "Oasis Fairy 4", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_4)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_5] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x04, "Oasis Fairy 5", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_5)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_6] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x05, "Oasis Fairy 6", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_6)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_7] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x06, "Oasis Fairy 7", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_7)); - locationTable[RC_COLOSSUS_OASIS_FAIRY_8] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x07, "Oasis Fairy 8", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_8)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x00, "Shield Grave Fairy 1", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x01, "Shield Grave Fairy 2", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x02, "Shield Grave Fairy 3", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x03, "Shield Grave Fairy 4", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x04, "Shield Grave Fairy 5", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x05, "Shield Grave Fairy 6", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x06, "Shield Grave Fairy 7", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x07, "Shield Grave Fairy 8", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_1] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_2] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_3] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_4] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_5] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_6] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_7] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_8] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "MQ Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "MQ Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "MQ Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "MQ Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_1] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x00, "Oasis Fairy 1", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_1)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_2] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x01, "Oasis Fairy 2", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_2)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_3] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x02, "Oasis Fairy 3", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_3)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_4] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x03, "Oasis Fairy 4", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_4)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_5] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x04, "Oasis Fairy 5", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_5)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_6] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x05, "Oasis Fairy 6", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_6)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_7] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x06, "Oasis Fairy 7", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_7)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_8] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x07, "Oasis Fairy 8", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_8)); - locationTable[RC_ZR_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0300, "Bean Sprout Fairy 1", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_ZR_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0301, "Bean Sprout Fairy 2", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_ZR_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0302, "Bean Sprout Fairy 3", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_KF_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0900, "Bean Sprout Fairy 1", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_KF_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0901, "Bean Sprout Fairy 2", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_KF_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0902, "Bean Sprout Fairy 3", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0400, "Bean Sprout Near Bridge Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0401, "Bean Sprout Near Bridge Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0402, "Bean Sprout Near Bridge Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1200, "Bean Sprout Near Theatre Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1201, "Bean Sprout Near Theatre Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2)); - locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1202, "Bean Sprout Near Theatre Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3)); - locationTable[RC_LH_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0100, "Bean Sprout Fairy 1", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_LH_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0101, "Bean Sprout Fairy 2", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_LH_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0102, "Bean Sprout Fairy 3", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_GV_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0300, "Bean Sprout Fairy 1", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_GV_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0301, "Bean Sprout Fairy 2", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_GV_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0302, "Bean Sprout Fairy 3", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1800, "Bean Sprout Fairy 1", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1801, "Bean Sprout Fairy 2", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1802, "Bean Sprout Fairy 3", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0300, "Bean Sprout Fairy 1", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0301, "Bean Sprout Fairy 2", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0302, "Bean Sprout Fairy 3", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_DMC_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0300, "Bean Sprout Fairy 1", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_DMC_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0301, "Bean Sprout Fairy 2", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_DMC_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0302, "Bean Sprout Fairy 3", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_DMT_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0600, "Bean Sprout Fairy 1", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_1)); - locationTable[RC_DMT_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0601, "Bean Sprout Fairy 2", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_2)); - locationTable[RC_DMT_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0602, "Bean Sprout Fairy 3", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0300, "Bean Sprout Fairy 1", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0301, "Bean Sprout Fairy 2", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0302, "Bean Sprout Fairy 3", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0900, "Bean Sprout Fairy 1", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0901, "Bean Sprout Fairy 2", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0902, "Bean Sprout Fairy 3", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0400, "Bean Sprout Near Bridge Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0401, "Bean Sprout Near Bridge Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0402, "Bean Sprout Near Bridge Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1200, "Bean Sprout Near Theatre Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1201, "Bean Sprout Near Theatre Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1202, "Bean Sprout Near Theatre Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0100, "Bean Sprout Fairy 1", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0101, "Bean Sprout Fairy 2", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0102, "Bean Sprout Fairy 3", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0300, "Bean Sprout Fairy 1", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0301, "Bean Sprout Fairy 2", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0302, "Bean Sprout Fairy 3", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1800, "Bean Sprout Fairy 1", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1801, "Bean Sprout Fairy 2", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1802, "Bean Sprout Fairy 3", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0300, "Bean Sprout Fairy 1", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0301, "Bean Sprout Fairy 2", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0302, "Bean Sprout Fairy 3", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0300, "Bean Sprout Fairy 1", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0301, "Bean Sprout Fairy 2", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0302, "Bean Sprout Fairy 3", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0600, "Bean Sprout Fairy 1", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0601, "Bean Sprout Fairy 2", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0602, "Bean Sprout Fairy 3", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_3)); - locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -680), "ToT Left Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY)); - locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -680), "ToT Left Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -615), "ToT Left Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY)); - locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -615), "ToT Left Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -550), "ToT Right Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY)); - locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -550), "ToT Right Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -485), "ToT Right Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY)); - locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -485), "ToT Right Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DMC_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS( 0, 1656), "Gossip Stone Fairy", RHT_DMC_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY)); - locationTable[RC_DMC_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(0x1000, 1656), "Gossip Stone Big Fairy", RHT_DMC_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DMT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS( 0, -3935), "Gossip Stone Fairy", RHT_DMT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY)); - locationTable[RC_DMT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, -3935), "Gossip Stone Big Fairy", RHT_DMT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS( 0, 1320), "Gossip Stone Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY)); - locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(0x1000, 1320), "Gossip Stone Big Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -1520), "Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY)); - locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -1520), "Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -916), "MQ Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY)); - locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -916), "MQ Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_GV_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS( 0, -2340), "Gossip Stone Fairy", RHT_GV_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY)); - locationTable[RC_GV_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(0x1000, -2340), "Gossip Stone Big Fairy", RHT_GV_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, -1265), "Maze Gossip Stone Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY)); - locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, -1265), "Maze Gossip Stone Big Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, 1496), "Medigoron Gossip Stone Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY)); - locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, 1496), "Medigoron Gossip Stone Big Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS( 0, -75), "Gossip Stone Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY)); - locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(0x1000, -75), "Gossip Stone Big Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 3445), "Malon Gossip Stone Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY)); - locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 3445), "Malon Gossip Stone Big Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 1041), "Rock Wall Gossip Stone Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY)); - locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 1041), "Rock Wall Gossip Stone Big Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xC, 735), "Storms Grotto Gossip Stone Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100C, 735), "Storms Grotto Gossip Stone Big Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -2230), "Deku Tree Left Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY)); - locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -2230), "Deku Tree Left Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -700), "Deku Tree Right Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY)); - locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -700), "Deku Tree Right Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_KF_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -1223), "Gossip Stone Fairy", RHT_KF_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY)); - locationTable[RC_KF_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -1223), "Gossip Stone Big Fairy", RHT_KF_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1B, -236), "Storms Gossip Stone Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101B, -236), "Storms Gossip Stone Big Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 3212), "Lab Gossip Stone Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY)); - locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 3212), "Lab Gossip Stone Big Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 8395), "Southeast Gossip Stone Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY)); - locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 8395), "Southeast Gossip Stone Big Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 7984), "Southwest Gossip Stone Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY)); - locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7984), "Southwest Gossip Stone Big Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LW_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS( 0, 2300), "Gossip Stone Fairy", RHT_LW_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY)); - locationTable[RC_LW_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, 2300), "Gossip Stone Big Fairy", RHT_LW_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 1370), "Maze Lower Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY)); - locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 1370), "Maze Lower Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 740), "Maze Upper Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY)); - locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 740), "Maze Upper Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, -2300), "Saria Gossip Stone Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY)); - locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, -2300), "Saria Gossip Stone Big Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS( 0, -1600), "Gossip Stone Fairy", RHT_ZD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(0x1000, -1600), "Gossip Stone Big Fairy", RHT_ZD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, 2205), "Fairy Gossip Stone Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, 2205), "Fairy Gossip Stone Big Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, -985), "Jabu Gossip Stone Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, -985), "Jabu Gossip Stone Big Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1070), "Near Grottos Gossip Stone Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1070), "Near Grottos Gossip Stone Big Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1650), "Near Domain Gossip Stone Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1650), "Near Domain Gossip Stone Big Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x11, -357), "Cow Grotto Gossip Stone Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1011, -357), "Cow Grotto Gossip Stone Big Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x10, -236), "Near Market Gossip Stone Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1010, -236), "Near Market Gossip Stone Big Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x14, -236), "Southeast Gossip Stone Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1014, -236), "Southeast Gossip Stone Big Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x13, -236), "Open Grotto Gossip Stone Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1013, -236), "Open Grotto Gossip Stone Big Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xA, -236), "Open Grotto Gossip Stone Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100A, -236), "Open Grotto Gossip Stone Big Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x4, -236), "Open Grotto Gossip Stone Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1004, -236), "Open Grotto Gossip Stone Big Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1A, -236), "Tunnel Grotto Gossip Stone Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101A, -236), "Tunnel Grotto Gossip Stone Big Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x8, -236), "Storms Grotto Gossip Stone Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1008, -236), "Storms Grotto Gossip Stone Big Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x6, -236), "Upper Grotto Gossip Stone Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY)); - locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1006, -236), "Upper Grotto Gossip Stone Big Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -680), "ToT Left Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -680), "ToT Left Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -615), "ToT Left Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -615), "ToT Left Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -550), "ToT Right Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -550), "ToT Right Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -485), "ToT Right Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -485), "ToT Right Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMC_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMC_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS( 0, 1656), "Gossip Stone Fairy", RHT_DMC_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMC_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMC_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(0x1000, 1656), "Gossip Stone Big Fairy", RHT_DMC_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS( 0, -3935), "Gossip Stone Fairy", RHT_DMT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, -3935), "Gossip Stone Big Fairy", RHT_DMT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS( 0, 1320), "Gossip Stone Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY)); + locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(0x1000, 1320), "Gossip Stone Big Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -1520), "Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY)); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -1520), "Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -916), "MQ Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY)); + locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -916), "MQ Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GV_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GV_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS( 0, -2340), "Gossip Stone Fairy", RHT_GV_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY)); + locationTable[RC_GV_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GV_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(0x1000, -2340), "Gossip Stone Big Fairy", RHT_GV_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, -1265), "Maze Gossip Stone Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY)); + locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, -1265), "Maze Gossip Stone Big Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, 1496), "Medigoron Gossip Stone Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY)); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, 1496), "Medigoron Gossip Stone Big Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS( 0, -75), "Gossip Stone Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY)); + locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(0x1000, -75), "Gossip Stone Big Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_MALON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 3445), "Malon Gossip Stone Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 3445), "Malon Gossip Stone Big Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 1041), "Rock Wall Gossip Stone Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 1041), "Rock Wall Gossip Stone Big Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xC, 735), "Storms Grotto Gossip Stone Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100C, 735), "Storms Grotto Gossip Stone Big Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -2230), "Deku Tree Left Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -2230), "Deku Tree Left Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -700), "Deku Tree Right Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -700), "Deku Tree Right Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -1223), "Gossip Stone Fairy", RHT_KF_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -1223), "Gossip Stone Big Fairy", RHT_KF_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1B, -236), "Storms Gossip Stone Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101B, -236), "Storms Gossip Stone Big Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_LAB_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 3212), "Lab Gossip Stone Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 3212), "Lab Gossip Stone Big Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 8395), "Southeast Gossip Stone Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 8395), "Southeast Gossip Stone Big Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 7984), "Southwest Gossip Stone Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7984), "Southwest Gossip Stone Big Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LW_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LW_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS( 0, 2300), "Gossip Stone Fairy", RHT_LW_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY)); + locationTable[RC_LW_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LW_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, 2300), "Gossip Stone Big Fairy", RHT_LW_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 1370), "Maze Lower Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 1370), "Maze Lower Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 740), "Maze Upper Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 740), "Maze Upper Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, -2300), "Saria Gossip Stone Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, -2300), "Saria Gossip Stone Big Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZD_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS( 0, -1600), "Gossip Stone Fairy", RHT_ZD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZD_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(0x1000, -1600), "Gossip Stone Big Fairy", RHT_ZD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, 2205), "Fairy Gossip Stone Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, 2205), "Fairy Gossip Stone Big Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, -985), "Jabu Gossip Stone Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, -985), "Jabu Gossip Stone Big Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1070), "Near Grottos Gossip Stone Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1070), "Near Grottos Gossip Stone Big Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1650), "Near Domain Gossip Stone Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1650), "Near Domain Gossip Stone Big Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x11, -357), "Cow Grotto Gossip Stone Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1011, -357), "Cow Grotto Gossip Stone Big Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x10, -236), "Near Market Gossip Stone Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1010, -236), "Near Market Gossip Stone Big Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x14, -236), "Southeast Gossip Stone Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1014, -236), "Southeast Gossip Stone Big Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x13, -236), "Open Grotto Gossip Stone Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1013, -236), "Open Grotto Gossip Stone Big Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xA, -236), "Open Grotto Gossip Stone Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100A, -236), "Open Grotto Gossip Stone Big Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x4, -236), "Open Grotto Gossip Stone Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1004, -236), "Open Grotto Gossip Stone Big Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1A, -236), "Tunnel Grotto Gossip Stone Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101A, -236), "Tunnel Grotto Gossip Stone Big Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x8, -236), "Storms Grotto Gossip Stone Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1008, -236), "Storms Grotto Gossip Stone Big Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x6, -236), "Upper Grotto Gossip Stone Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1006, -236), "Upper Grotto Gossip Stone Big Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG)); - locationTable[RC_LH_ISLAND_SUN_FAIRY] = Location::Fairy(RC_LH_ISLAND_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7319), "Island Sun's Song Fairy", RHT_LH_ISLAND_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_SUN_FAIRY)); - locationTable[RC_HF_POND_STORMS_FAIRY] = Location::Fairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY)); - locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -308), "Deku Scrub Grotto Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCE_GROTTO_STORMS_FAIRY)); - locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::Fairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY)); - locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY)); - locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::Fairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY)); - locationTable[RC_TH_KITCHEN_SUN_FAIRY] = Location::Fairy(RC_TH_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", RHT_TH_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_SUN_FAIRY)); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::Fairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Deku Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY)); - locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::Fairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Royal Family's Tomb Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY)); + locationTable[RC_LH_ISLAND_SUN_FAIRY] = Location::SongFairy(RC_LH_ISLAND_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7319), "Island Sun's Song Fairy", RHT_LH_ISLAND_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_SUN_FAIRY)); + locationTable[RC_HF_POND_STORMS_FAIRY] = Location::SongFairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY)); + locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::SongFairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -308), "Deku Scrub Grotto Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCE_GROTTO_STORMS_FAIRY)); + locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::SongFairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY)); + locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::SongFairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY)); + locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::SongFairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY)); + locationTable[RC_TH_KITCHEN_SUN_FAIRY] = Location::SongFairy(RC_TH_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", RHT_TH_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_SUN_FAIRY)); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::SongFairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Deku Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY)); + locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::SongFairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Royal Family's Tomb Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY)); - locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY)); - locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 54), "Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3339), "Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY)); - locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1531), "Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY)); - locationTable[RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(0x1000, 1186), "Entrance Song of Storms Fairy", RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY)); - locationTable[RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_GERUDO_TRAINING_GROUND,SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(0x1000, -445), "Entrance Song of Storms Fairy", RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY)); - locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = Location::Fairy(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(0x1000, 587), "Spirit Trial Beamos Sun's Song Fairy", RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY)); + locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY)); + locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 54), "Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_PIT_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3339), "Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1531), "Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY)); + locationTable[RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = Location::SongFairy(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(0x1000, 1186), "Entrance Song of Storms Fairy", RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY)); + locationTable[RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = Location::SongFairy(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_GERUDO_TRAINING_GROUND,SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(0x1000, -445), "Entrance Song of Storms Fairy", RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = Location::SongFairy(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(0x1000, 587), "Spirit Trial Beamos Sun's Song Fairy", RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY)); - locationTable[RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -551), "MQ Lower Loop Stalfos Room Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY)); - locationTable[RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1563), "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY)); - locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -540), "MQ Before Dark Link Pilar Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY)); - locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1501), "MQ Before Dark Link Left Song of Storms Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY)); - locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1504), "MQ Before Dark Link Right Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY)); - locationTable[RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "MQ Dinalfos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 55), "MQ Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3342), "MQ Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY)); - locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "MQ Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY)); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -437), "MQ East Cell Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY)); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY)); + locationTable[RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = Location::SongFairy(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -551), "MQ Lower Loop Stalfos Room Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY)); + locationTable[RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = Location::SongFairy(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1563), "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -540), "MQ Before Dark Link Pilar Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1501), "MQ Before Dark Link Left Song of Storms Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1504), "MQ Before Dark Link Right Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY)); + locationTable[RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "MQ Dinalfos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 55), "MQ Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3342), "MQ Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "MQ Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -437), "MQ East Cell Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY)); // clang-format on } diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 9bb7247d1..898c9ea38 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -52,7 +52,10 @@ Context::Context() { &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], - &mOptions[RSK_SHUFFLE_FAIRIES], + &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], + &mOptions[RSK_SHUFFLE_STONE_FAIRIES], + &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], + &mOptions[RSK_SHUFFLE_SONG_FAIRIES], &mOptions[RSK_GOSSIP_STONE_HINTS], }; } @@ -194,7 +197,10 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || - (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || + (location.GetRCType() == RCTYPE_FOUNTAIN_FAIRY && !mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES]) || + (location.GetRCType() == RCTYPE_STONE_FAIRY && !mOptions[RSK_SHUFFLE_STONE_FAIRIES]) || + (location.GetRCType() == RCTYPE_BEAN_FAIRY && !mOptions[RSK_SHUFFLE_BEAN_FAIRIES]) || + (location.GetRCType() == RCTYPE_SONG_FAIRY && !mOptions[RSK_SHUFFLE_SONG_FAIRIES]) || (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || (location.GetRCType() == RCTYPE_NLTREE && (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index e23c91d2a..847ee9aa9 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -592,11 +592,37 @@ Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQu false }; } -Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { - return { rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_), - hintKey, RG_NONE, false, collectionCheck }; +Rando::Location Rando::Location::FountainFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_FOUNTAIN_FAIRY, area_, ACTOR_EN_ELF, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} + +Rando::Location Rando::Location::StoneFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_STONE_FAIRY, area_, ACTOR_EN_ELF, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} + +Rando::Location Rando::Location::BeanFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BEAN_FAIRY, area_, ACTOR_EN_ELF, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; +} + +Rando::Location Rando::Location::SongFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_SONG_FAIRY, area_, ACTOR_EN_ELF, + scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, + false, collectionCheck }; } Rando::Location Rando::Location::Grass(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 9c565344f..f118bdcda 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -263,9 +263,21 @@ class Location { static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_); - static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, - SpoilerCollectionCheck collectionCheck); + static Location FountainFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + + static Location StoneFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + + static Location BeanFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + + static Location SongFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 2fea752cc..e13e2f5b3 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -104,10 +104,40 @@ std::vector Rando::StaticData::GetAllDungeonLocations() { return dungeonLocations; } -std::vector Rando::StaticData::GetOverworldFairyLocations() { +std::vector Rando::StaticData::GetFountainFairyLocations() { std::vector fairyLocations = {}; for (Location& location : locationTable) { - if (location.GetRCType() == RCTYPE_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + if (location.GetRCType() == RCTYPE_FOUNTAIN_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + fairyLocations.push_back(location.GetRandomizerCheck()); + } + } + return fairyLocations; +} + +std::vector Rando::StaticData::GetStoneFairyLocations() { + std::vector fairyLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_STONE_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + fairyLocations.push_back(location.GetRandomizerCheck()); + } + } + return fairyLocations; +} + +std::vector Rando::StaticData::GetBeanFairyLocations() { + std::vector fairyLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_BEAN_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + fairyLocations.push_back(location.GetRandomizerCheck()); + } + } + return fairyLocations; +} + +std::vector Rando::StaticData::GetSongFairyLocations() { + std::vector fairyLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_SONG_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { fairyLocations.push_back(location.GetRandomizerCheck()); } } diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index ce9b261d6..24e08bd28 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -481,7 +481,15 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" "\n" "All Items - Shuffle all freestanding rupees & hearts."; - mOptionDescriptions[RSK_SHUFFLE_FAIRIES] = "Shuffle fairy locations."; + mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES] = + "Shuffle fairies in fountain locations. " + "This includes the sets of fairies found in Ganon's Castle and the Desert Oasis."; + mOptionDescriptions[RSK_SHUFFLE_STONE_FAIRIES] = "Shuffle fairies from gossip stone locations."; + mOptionDescriptions[RSK_SHUFFLE_BEAN_FAIRIES] = "Shuffle fairies from magic bean locations."; + mOptionDescriptions[RSK_SHUFFLE_SONG_FAIRIES] = + "Shuffle fairy spots. These are spots where a big fairy is revealed by a song." + "\n" + "This excludes gossip stones and magic bean locations."; mOptionDescriptions[RSK_SHUFFLE_GRASS] = "Grass/Bushes will drop a randomized item the first time they're cut and collected. " "Grass/Bushes will have a different appearance when they hold a randomized item.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c3adadcec..29c725341 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -423,7 +423,10 @@ typedef enum { RCTYPE_BEEHIVE, // Beehives RCTYPE_FISH, // Fishes RCTYPE_FREESTANDING, // Freestanding rupees and hearts - RCTYPE_FAIRY, // Fairies + RCTYPE_FOUNTAIN_FAIRY, // Fairies in Fountains + RCTYPE_STONE_FAIRY, // Fairies from Gossip Stones + RCTYPE_BEAN_FAIRY, // Fairies from Beans + RCTYPE_SONG_FAIRY, // Fairies from Songs RCTYPE_GRASS, // Grass } RandomizerCheckType; @@ -6138,7 +6141,10 @@ typedef enum { RSK_SHUFFLE_DEKU_STICK_BAG, RSK_SHUFFLE_DEKU_NUT_BAG, RSK_SHUFFLE_FREESTANDING, - RSK_SHUFFLE_FAIRIES, + RSK_SHUFFLE_FOUNTAIN_FAIRIES, + RSK_SHUFFLE_STONE_FAIRIES, + RSK_SHUFFLE_BEAN_FAIRIES, + RSK_SHUFFLE_SONG_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, RSK_MAX diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index f8a73ddd2..fa1e7158b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -207,8 +207,14 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FROG_SONG || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_FAIRY || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFairies"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_FOUNTAIN_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFountainFairies"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_STONE_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleStoneFairies"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_BEAN_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_SONG_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"), RO_GENERIC_NO)) && ((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 6a468ff64..022303aa3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -84,7 +84,10 @@ bool showOverworldCrates; bool showDungeonCrates; bool showTrees; bool showFrogSongRupees; -bool showFairies; +bool showFountainFairies; +bool showStoneFairies; +bool showBeanFairies; +bool showSongFairies; bool showStartingMapsCompasses; bool showKeysanity; bool showGerudoFortressKeys; @@ -1366,9 +1369,19 @@ void LoadSettings() { IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES : false; - showFairies = IS_RANDO - ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) == RO_GENERIC_YES - : false; + showFountainFairies = + IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FOUNTAIN_FAIRIES) == RO_GENERIC_YES + : false; + showStoneFairies = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_STONE_FAIRIES) == RO_GENERIC_YES + : false; + showBeanFairies = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEAN_FAIRIES) == RO_GENERIC_YES + : false; + showSongFairies = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SONG_FAIRIES) == RO_GENERIC_YES + : false; showStartingMapsCompasses = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA : false; @@ -1613,7 +1626,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (rc != RC_HC_MALON_EGG || showWeirdEgg) && (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && - (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && + (loc->GetRCType() != RCTYPE_FOUNTAIN_FAIRY || showFountainFairies) && + (loc->GetRCType() != RCTYPE_STONE_FAIRY || showStoneFairies) && + (loc->GetRCType() != RCTYPE_BEAN_FAIRY || showBeanFairies) && + (loc->GetRCType() != RCTYPE_SONG_FAIRY || showSongFairies) && (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 7f67f946b..006646449 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -241,7 +241,10 @@ void Settings::CreateOptions() { OPT_U8(RSK_FISHSANITY, "Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); OPT_U8(RSK_FISHSANITY_POND_COUNT, "Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); OPT_BOOL(RSK_FISHSANITY_AGE_SPLIT, "Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); - OPT_BOOL(RSK_SHUFFLE_FAIRIES, "Shuffle Fairies", CVAR_RANDOMIZER_SETTING("ShuffleFairies"), mOptionDescriptions[RSK_SHUFFLE_FAIRIES]); + OPT_BOOL(RSK_SHUFFLE_FOUNTAIN_FAIRIES, "Shuffle Fairies in Fountains", CVAR_RANDOMIZER_SETTING("ShuffleFountainFairies"), mOptionDescriptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES]); + OPT_BOOL(RSK_SHUFFLE_STONE_FAIRIES, "Shuffle Gossip Stone Fairies", CVAR_RANDOMIZER_SETTING("ShuffleStoneFairies"), mOptionDescriptions[RSK_SHUFFLE_STONE_FAIRIES]); + OPT_BOOL(RSK_SHUFFLE_BEAN_FAIRIES, "Shuffle Bean Fairies", CVAR_RANDOMIZER_SETTING("ShuffleBeanFairies"), mOptionDescriptions[RSK_SHUFFLE_BEAN_FAIRIES]); + OPT_BOOL(RSK_SHUFFLE_SONG_FAIRIES, "Shuffle Fairy Spots", CVAR_RANDOMIZER_SETTING("ShuffleFairySpots"), mOptionDescriptions[RSK_SHUFFLE_SONG_FAIRIES]); OPT_U8(RSK_SHUFFLE_MAPANDCOMPASS, "Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); OPT_U8(RSK_KEYSANITY, "Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); OPT_U8(RSK_GERUDO_KEYS, "Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); @@ -1312,7 +1315,10 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], - &mOptions[RSK_SHUFFLE_FAIRIES], + &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], + &mOptions[RSK_SHUFFLE_STONE_FAIRIES], + &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], + &mOptions[RSK_SHUFFLE_SONG_FAIRIES], &mOptions[RSK_SHUFFLE_GRASS], }, WidgetContainerType::COLUMN); @@ -1574,7 +1580,10 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], - &mOptions[RSK_SHUFFLE_FAIRIES], + &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], + &mOptions[RSK_SHUFFLE_STONE_FAIRIES], + &mOptions[RSK_SHUFFLE_BEAN_FAIRIES], + &mOptions[RSK_SHUFFLE_SONG_FAIRIES], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index d6a151391..cd24667a0 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -48,7 +48,10 @@ class StaticData { static std::vector GetStaticHintLocations(); static std::vector GetPondFishLocations(); static std::vector GetOverworldFishLocations(); - static std::vector GetOverworldFairyLocations(); + static std::vector GetFountainFairyLocations(); + static std::vector GetStoneFairyLocations(); + static std::vector GetBeanFairyLocations(); + static std::vector GetSongFairyLocations(); static void RegisterSongLocations(); static void RegisterBeehiveLocations(); static void RegisterCowLocations();