diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d200a2d771..64975a34b22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,37 @@ include(CMake/lus-cvars.cmake) set(PROJECT_BUILD_NAME "MacReady Golf" CACHE STRING "" FORCE) set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "" FORCE) +execute_process( + COMMAND git branch --show-current + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +set(CMAKE_PROJECT_GIT_BRANCH "${GIT_BRANCH}" CACHE STRING "Git branch" FORCE) + +execute_process( + COMMAND git rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +set(CMAKE_PROJECT_GIT_COMMIT_HASH "${GIT_COMMIT_HASH}" CACHE STRING "Git commit hash" FORCE) + +execute_process( + COMMAND git describe --tags --abbrev=0 --exact-match HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(NOT GIT_COMMIT_TAG) + set(GIT_COMMIT_TAG "" CACHE STRING "Git commit tag" FORCE) +endif() + +set(CMAKE_PROJECT_GIT_COMMIT_TAG "${GIT_COMMIT_TAG}" CACHE STRING "Git commit tag" FORCE) + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) add_compile_options($<$:/MP>) add_compile_options($<$:/utf-8>) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index eb5a6a3365c..471a493ac64 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -6,7 +6,7 @@ Requires: * At least 8GB of RAM (machines with 4GB have seen complier failures) * Visual Studio 2022 Community Edition with the C++ feature set * One of the Windows SDKs that comes with Visual Studio, for example the current Windows 10 version 10.0.19041.0 - * The `MSVC v142 - VS 2019 C++ build tools` component of Visual Studio + * The `MSVC v143 - VS 2022 C++ build tools` component of Visual Studio * Python 3 (can be installed manually or as part of Visual Studio) * Git (can be installed manually or as part of Visual Studio) * Cmake (can be installed via chocolatey or manually) @@ -14,12 +14,9 @@ Requires: During installation, check the "Desktop development with C++" feature set: ![image](https://user-images.githubusercontent.com/30329717/183511274-d11aceea-7900-46ec-acb6-3f2cc110021a.png) -Doing so should also check one of the Windows SDKs by default. Then, in the installation details in the right-hand column, make sure you also check the v142 toolset. +Doing so should also check one of the Windows SDKs by default. Then, in the installation details in the right-hand column, make sure you also check the v143 toolset. This is often done by default. -You can also find the v142 toolset by searching through the individual components tab: - -![image](https://user-images.githubusercontent.com/30329717/183521169-ead6a73b-a1bf-4e99-aab8-441746d8f08e.png) -While you're there, you can also install Python 3 and Git if needed. +It is recommended that you install Python and Git standalone, the install process in VS Installer has given some issues in the past. 1. Clone the Ship of Harkinian repository @@ -33,9 +30,7 @@ _Note: Instructions assume using powershell_ cd Shipwright # Setup cmake project -& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v142 -A x64 # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -# or for VS2019 -& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 16 2019" -T v142 -A x64 +& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64 # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) # Extract assets & generate OTR (run this anytime you need to regenerate OTR) & 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssets # --config Release (if you're packaging) # Compile project @@ -60,9 +55,7 @@ With the cmake build system you have two options for working on the project: To develop using Visual Studio you only need to use cmake to generate the solution file: ```powershell # Generates Ship.sln at `build/x64` for Visual Studio 2022 -& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v142 -A x64 -# or for Visual Studio 2019 -& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 16 2019" -T v142 -A x64 +& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64 ``` #### Visual Studio Code or another editor diff --git a/libultraship b/libultraship index 31e9b009f94..0302eab051a 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 31e9b009f94e7074a847c7954926cba354cd7c72 +Subproject commit 0302eab051a7e0e5a8dc208aca5b00899a91808c diff --git a/soh/include/variables.h b/soh/include/variables.h index 0f50e224902..5c97b26b8a8 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -49,7 +49,10 @@ extern "C" extern u16 gBuildVersionMajor; extern u16 gBuildVersionMinor; extern u16 gBuildVersionPatch; - extern u8 gBuildTeam[]; + extern u8 gGitBranch[]; + extern u8 gGitCommitHash[]; + extern u8 gGitCommitTag[]; + extern u8 gBuildTeam[]; extern u8 gBuildDate[]; extern u8 gBuildMakeOption[]; extern OSMesgQueue gPiMgrCmdQ; diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 617c2acf526..c6db012e1df 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -68,6 +68,7 @@ typedef enum { // Pre-existing IDs for save sections in base code SECTION_ID_STATS, SECTION_ID_ENTRANCES, SECTION_ID_SCENES, + SECTION_ID_TRACKER_DATA, SECTION_ID_MAX } SaveFuncIDs; @@ -279,7 +280,6 @@ typedef struct { /* */ u8 pendingIceTrapCount; /* */ SohStats sohStats; /* */ FaroresWindData backupFW; - /* */ RandomizerCheckTrackerData checkTrackerData[RC_MAX]; // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer diff --git a/soh/soh/CrashHandlerExt.cpp b/soh/soh/CrashHandlerExt.cpp index 14f0714ffa9..c4a535f1216 100644 --- a/soh/soh/CrashHandlerExt.cpp +++ b/soh/soh/CrashHandlerExt.cpp @@ -69,6 +69,8 @@ extern "C" void CrashHandler_PrintSohData(char* buffer, size_t* pos) { char intCharBuffer[16]; append_line(buffer, pos, "Build Information:"); WRITE_VAR_LINE(buffer, pos, "Game Version: ", (const char*)gBuildVersion); + WRITE_VAR_LINE(buffer, pos, "Git Branch: ", (const char*)gGitBranch); + WRITE_VAR_LINE(buffer, pos, "Git Commit: ", (const char*)gGitCommitHash); WRITE_VAR_LINE(buffer, pos, "Build Date: ", (const char*)gBuildDate); if (gPlayState != nullptr) { diff --git a/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp b/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp new file mode 100644 index 00000000000..ca73877c610 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp @@ -0,0 +1,58 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "spdlog/spdlog.h" + +extern "C" { + #include "z64save.h" + #include "macros.h" + #include "variables.h" + #include "functions.h" + extern PlayState* gPlayState; + extern SaveContext gSaveContext; +} + +/** + * This primarily handles speeding up the heavy block lifts (OGC and in the Fire Trial) but also handles skipping + * the one point cutscene since the two options are so similar in what they do. + */ +void FasterHeavyBlockLift_Register() { + REGISTER_VB_SHOULD(VB_PLAY_ONEPOINT_ACTOR_CS, { + Actor* actor = static_cast(opt); + + if ( + actor->id == ACTOR_BG_HEAVY_BLOCK && + (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) + ) { + *should = false; + } + }); + + REGISTER_VB_SHOULD(VB_FREEZE_LINK_FOR_BLOCK_THROW, { + if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) { + *should = false; + } + }); + + REGISTER_VB_SHOULD(VB_PLAY_THROW_ANIMATION, { + Player *player = GET_PLAYER(gPlayState); + Actor* interactRangeActor = player->interactRangeActor; + s32 interactActorId = interactRangeActor->id; + LinkAnimationHeader* anim = static_cast(opt); + + // Same actor is used for small and large silver rocks, use actor params to identify large ones + bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1; + if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) && (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) { + *should = false; + LinkAnimation_PlayOnceSetSpeed(gPlayState, &player->skelAnime, anim, 5.0f); + } + }); + + REGISTER_VB_SHOULD(VB_MOVE_THROWN_ACTOR, { + if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) { + Actor* heldActor = static_cast(opt); + + heldActor->shape.rot.x -= 3510; + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index ec53c7ed01e..27dc30ae92c 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -19,19 +19,19 @@ extern "C" { */ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void* opt) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { - uint8_t isBlueWarp = 0; + uint8_t isBlueWarpCutscene = 0; // Deku Tree Blue warp if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // Dodongo's Cavern Blue warp } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_0 && gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // Jabu Jabu's Blue warp } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_0 && gSaveContext.cutsceneIndex == 0xFFF0) { gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_0; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // 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 @@ -43,14 +43,14 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12; } - isBlueWarp = 1; + isBlueWarpCutscene = 1; // Fire Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && gSaveContext.cutsceneIndex == 0xFFF3) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // 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 @@ -58,18 +58,18 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // 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_8; - isBlueWarp = 1; + isBlueWarpCutscene = 1; // 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_8; - isBlueWarp = 1; + isBlueWarpCutscene = 1; } - if (isBlueWarp) { + if (isBlueWarpCutscene) { if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_9) { // Normally set in the blue warp cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; @@ -77,10 +77,11 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void *should = false; gSaveContext.cutsceneIndex = 0; + } - if (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)) { - Entrance_OverrideBlueWarp(); - } + // This is outside the above condition because we want to handle both first and following visits to the blue warp + if (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)) { + Entrance_OverrideBlueWarp(); } } } diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp index f6d2e362963..68fe71da666 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp @@ -11,4 +11,5 @@ void TimeSavers_Register() { SkipIntro_Register(); // SkipMiscInteractions MoveMidoInKokiriForest_Register(); + FasterHeavyBlockLift_Register(); } diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.h b/soh/soh/Enhancements/TimeSavers/TimeSavers.h index b3b22135191..d45ed7f1085 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.h +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.h @@ -13,5 +13,6 @@ void TimeSavers_Register(); void SkipIntro_Register(); // SkipMiscInteractions void MoveMidoInKokiriForest_Register(); +void FasterHeavyBlockLift_Register(); #endif // TIME_SAVERS_H diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 3b0c2bb123b..a9fefbe7197 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -424,12 +424,6 @@ void AudioEditor::InitElement() { void AudioEditor::DrawElement() { AudioCollection::Instance->InitializeShufflePool(); - ImGui::SetNextWindowSize(ImVec2(820, 630), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Audio Editor", &mIsVisible)) { - ImGui::End(); - return; - } - float buttonSegments = ImGui::GetContentRegionAvail().x / 4; if (ImGui::Button("Randomize All Groups", ImVec2(buttonSegments, 30.0f))) { AudioEditor_RandomizeAll(); @@ -700,7 +694,6 @@ void AudioEditor::DrawElement() { ImGui::EndTabBar(); } - ImGui::End(); } std::vector allTypes = { SEQ_BGM_WORLD, SEQ_BGM_EVENT, SEQ_BGM_BATTLE, SEQ_OCARINA, SEQ_FANFARE, SEQ_INSTRUMENT, SEQ_SFX, SEQ_VOICE }; diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index 106a08b53e7..d4bd5405c77 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -61,6 +61,15 @@ void InputViewer::RenderButton(std::string btnTexture, std::string btnOutlineTex } } +void InputViewer::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); +} + void InputViewer::DrawElement() { if (CVarGetInteger(CVAR_WINDOW("InputViewer"), 0)) { static bool sButtonTexturesLoaded = false; @@ -73,60 +82,60 @@ void InputViewer::DrawElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn", - "textures/buttons/StartBtn.png"); + "textures/buttons/StartBtn.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick", - "textures/buttons/AnalogStick.png"); + "textures/buttons/AnalogStick.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left", - "textures/buttons/DPadLeft.png"); + "textures/buttons/DPadLeft.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right", - "textures/buttons/DPadRight.png"); + "textures/buttons/DPadRight.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down", - "textures/buttons/DPadDown.png"); + "textures/buttons/DPadDown.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1", "textures/buttons/Mod1.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2", "textures/buttons/Mod2.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick", - "textures/buttons/RightStick.png"); + "textures/buttons/RightStick.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline", - "textures/buttons/ABtnOutline.png"); + "textures/buttons/ABtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn Outline", - "textures/buttons/BBtnOutline.png"); + "textures/buttons/BBtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn Outline", - "textures/buttons/LBtnOutline.png"); + "textures/buttons/LBtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn Outline", - "textures/buttons/RBtnOutline.png"); + "textures/buttons/RBtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn Outline", - "textures/buttons/ZBtnOutline.png"); + "textures/buttons/ZBtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn Outline", - "textures/buttons/StartBtnOutline.png"); + "textures/buttons/StartBtnOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left Outline", - "textures/buttons/CLeftOutline.png"); + "textures/buttons/CLeftOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right Outline", - "textures/buttons/CRightOutline.png"); + "textures/buttons/CRightOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up Outline", - "textures/buttons/CUpOutline.png"); + "textures/buttons/CUpOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down Outline", - "textures/buttons/CDownOutline.png"); + "textures/buttons/CDownOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick Outline", - "textures/buttons/AnalogStickOutline.png"); + "textures/buttons/AnalogStickOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left Outline", - "textures/buttons/DPadLeftOutline.png"); + "textures/buttons/DPadLeftOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right Outline", - "textures/buttons/DPadRightOutline.png"); + "textures/buttons/DPadRightOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up Outline", - "textures/buttons/DPadUpOutline.png"); + "textures/buttons/DPadUpOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline", - "textures/buttons/DPadDownOutline.png"); + "textures/buttons/DPadDownOutline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1 Outline", - "textures/buttons/Mod1Outline.png"); + "textures/buttons/Mod1Outline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2 Outline", - "textures/buttons/Mod2Outline.png"); + "textures/buttons/Mod2Outline.png"); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline", - "textures/buttons/RightStickOutline.png"); + "textures/buttons/RightStickOutline.png"); sButtonTexturesLoaded = true; } @@ -147,12 +156,12 @@ void InputViewer::DrawElement() { ImGui::SetNextWindowSize( ImVec2(scaledBGSize.x + 20, scaledBGSize.y + - (showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * - CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + - 20)); + (showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * + CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + + 20)); ImGui::SetNextWindowContentSize( ImVec2(scaledBGSize.x, scaledBGSize.y + (showAnalogAngles ? 15 : 0) * scale * - CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f))); + CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f))); ImGui::SetNextWindowPos( ImVec2(mainPos.x + size.x - scaledBGSize.x - 30, mainPos.y + size.y - scaledBGSize.y - 30), ImGuiCond_FirstUseEver); @@ -163,8 +172,8 @@ void InputViewer::DrawElement() { OSContPad* pads = Ship::Context::GetInstance()->GetControlDeck()->GetPads(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | - ImGuiWindowFlags_NoFocusOnAppearing; + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | + ImGuiWindowFlags_NoFocusOnAppearing; if (!CVarGetInteger(CVAR_INPUT_VIEWER("EnableDragging"), 1)) { windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove; @@ -187,17 +196,17 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("B-Btn", "B-Btn Outline", pads[0].button & BTN_B, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("BBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("BBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("A-Btn", "A-Btn Outline", pads[0].button & BTN_A, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("ABtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("ABtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // C buttons @@ -205,33 +214,33 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Up", "C-Up Outline", pads[0].button & BTN_CUP, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CUpOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CUpOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Left", "C-Left Outline", pads[0].button & BTN_CLEFT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CLeftOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CLeftOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Right", "C-Right Outline", pads[0].button & BTN_CRIGHT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CRightOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CRightOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Down", "C-Down Outline", pads[0].button & BTN_CDOWN, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CDownOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CDownOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // L/R/Z @@ -239,25 +248,25 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("L-Btn", "L-Btn Outline", pads[0].button & BTN_L, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("LBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("LBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("R-Btn", "R-Btn Outline", pads[0].button & BTN_R, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("RBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("RBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Z-Btn", "Z-Btn Outline", pads[0].button & BTN_Z, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Start @@ -265,9 +274,9 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Start-Btn", "Start-Btn Outline", pads[0].button & BTN_START, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Dpad @@ -275,27 +284,27 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Left", "Dpad-Left Outline", pads[0].button & BTN_DLEFT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Right", "Dpad-Right Outline", pads[0].button & BTN_DRIGHT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Up", "Dpad-Up Outline", pads[0].button & BTN_DUP, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Down", "Dpad-Down Outline", pads[0].button & BTN_DDOWN, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Modifier 1 @@ -303,18 +312,18 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Modifier-1", "Modifier-1 Outline", pads[0].button & BTN_MODIFIER1, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("Mod1OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("Mod1OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Modifier 2 if (CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Modifier-2", "Modifier-2 Outline", pads[0].button & BTN_MODIFIER2, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("Mod2OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("Mod2OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } const bool analogStickIsInDeadzone = !pads[0].stick_x && !pads[0].stick_y; @@ -339,9 +348,9 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos( ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale, - aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); + aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); } // Right Stick @@ -363,15 +372,15 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos( ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale, - aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale)); + aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale)); ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); } // Analog stick angle text if (showAnalogAngles) { ImGui::SetCursorPos(ImVec2(aPos.x + 10 + CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0) * scale, - scaledBGSize.y + aPos.y + 10)); + scaledBGSize.y + aPos.y + 10)); // Scale font with input viewer scale float oldFontScale = ImGui::GetFont()->Scale; ImGui::GetFont()->Scale *= scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f); @@ -393,14 +402,16 @@ void InputViewer::DrawElement() { ImGui::PushStyleColor( ImGuiCol_Text, color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color)))); - } else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) && - (rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) { + } + else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) && + (rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) { ImGui::PushStyleColor( ImGuiCol_Text, color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color)))); - } else { + } + else { ImGui::PushStyleColor(ImGuiCol_Text, color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), - vec2Color(textColor)))); + vec2Color(textColor)))); } // Render text @@ -425,257 +436,250 @@ InputViewerSettingsWindow::~InputViewerSettingsWindow() { } void InputViewerSettingsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(500, 525), ImGuiCond_FirstUseEver); - - if (ImGui::Begin("Input Viewer Settings", &mIsVisible, ImGuiWindowFlags_HorizontalScrollbar)) { - - // gInputViewer.Scale - UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", CVAR_INPUT_VIEWER("Scale"), 0.1f, 5.0f, "", - 1.0f, false, true); - UIWidgets::Tooltip("Sets the on screen size of the input viewer"); - - // gInputViewer.EnableDragging - UIWidgets::EnhancementCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); + // gInputViewer.Scale + UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", CVAR_INPUT_VIEWER("Scale"), 0.1f, 5.0f, "", + 1.0f, false, true); + UIWidgets::Tooltip("Sets the on screen size of the input viewer"); + + // gInputViewer.EnableDragging + UIWidgets::EnhancementCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + + UIWidgets::PaddedSeparator(true, true); + + // gInputViewer.ShowBackground + UIWidgets::EnhancementCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + + UIWidgets::PaddedSeparator(true, true); + + if (ImGui::CollapsingHeader("Buttons")) { + + // gInputViewer.ButtonOutlineMode + UIWidgets::PaddedText("Button Outlines/Backgrounds", true, false); + UIWidgets::EnhancementCombobox( + CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions, BUTTON_OUTLINE_NOT_PRESSED, + !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1), "", + CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + UIWidgets::Tooltip( + "Sets the desired visibility behavior for the button outline/background layers. Useful for " + "custom input viewers."); + + // gInputViewer.UseGlobalButtonOutlineMode + UIWidgets::EnhancementCheckbox("Use for all buttons", CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + + UIWidgets::PaddedSeparator(); + + bool useIndividualOutlines = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1); + + // gInputViewer.ABtn + UIWidgets::EnhancementCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ABtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.BBtn + UIWidgets::EnhancementCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("BBtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.CUp + UIWidgets::EnhancementCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CUpOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.CRight + UIWidgets::EnhancementCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CRightOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.CDown + UIWidgets::EnhancementCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CDownOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.CLeft + UIWidgets::EnhancementCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CLeftOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.LBtn + UIWidgets::EnhancementCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("LBtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.RBtn + UIWidgets::EnhancementCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RBtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.ZBtn + UIWidgets::EnhancementCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.StartBtn + UIWidgets::EnhancementCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, true); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.Dpad + UIWidgets::EnhancementCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, false); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("DpadOutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.Mod1 + UIWidgets::EnhancementCheckbox("Show Modifier Button 1 Layers", CVAR_INPUT_VIEWER("Mod1"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, false); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod1"), 0)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod1OutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } + // gInputViewer.Mod2 + UIWidgets::EnhancementCheckbox("Show Modifier Button 2 Layers", CVAR_INPUT_VIEWER("Mod2"), false, "", + UIWidgets::CheckboxGraphics::Checkmark, false); + if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) { + ImGui::Indent(); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod2OutlineMode"), buttonOutlineOptionsVerbose, + BUTTON_OUTLINE_NOT_PRESSED); + ImGui::Unindent(); + } UIWidgets::PaddedSeparator(true, true); + } - // gInputViewer.ShowBackground - UIWidgets::EnhancementCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - + if (ImGui::CollapsingHeader("Analog Stick")) { + // gInputViewer.AnalogStick.VisibilityMode + UIWidgets::PaddedText("Analog Stick Visibility", true, false); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions, + STICK_MODE_ALWAYS_SHOWN); + UIWidgets::Tooltip( + "Determines the conditions under which the moving layer of the analog stick texture is visible."); + + // gInputViewer.AnalogStick.OutlineMode + UIWidgets::PaddedText("Analog Stick Outline/Background Visibility", true, false); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), stickModeOptions, + STICK_MODE_ALWAYS_SHOWN); + UIWidgets::Tooltip( + "Determines the conditions under which the analog stick outline/background texture is visible."); + + // gInputViewer.AnalogStick.Movement + UIWidgets::EnhancementSliderInt("Analog Stick Movement: %dpx", "##AnalogMovement", + CVAR_INPUT_VIEWER("AnalogStick.Movement"), 0, 200, "", 12, true); + UIWidgets::Tooltip( + "Sets the distance to move the analog stick in the input viewer. Useful for custom input viewers."); UIWidgets::PaddedSeparator(true, true); + } - if (ImGui::CollapsingHeader("Buttons")) { - - // gInputViewer.ButtonOutlineMode - UIWidgets::PaddedText("Button Outlines/Backgrounds", true, false); - UIWidgets::EnhancementCombobox( - CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions, BUTTON_OUTLINE_NOT_PRESSED, - !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1), "", - CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); - UIWidgets::Tooltip( - "Sets the desired visibility behavior for the button outline/background layers. Useful for " - "custom input viewers."); - - // gInputViewer.UseGlobalButtonOutlineMode - UIWidgets::EnhancementCheckbox("Use for all buttons", CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - - UIWidgets::PaddedSeparator(); - - bool useIndividualOutlines = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1); - - // gInputViewer.ABtn - UIWidgets::EnhancementCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ABtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.BBtn - UIWidgets::EnhancementCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("BBtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.CUp - UIWidgets::EnhancementCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CUpOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.CRight - UIWidgets::EnhancementCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CRightOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.CDown - UIWidgets::EnhancementCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CDownOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.CLeft - UIWidgets::EnhancementCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CLeftOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.LBtn - UIWidgets::EnhancementCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("LBtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.RBtn - UIWidgets::EnhancementCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RBtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.ZBtn - UIWidgets::EnhancementCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.StartBtn - UIWidgets::EnhancementCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, true); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.Dpad - UIWidgets::EnhancementCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, false); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("DpadOutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.Mod1 - UIWidgets::EnhancementCheckbox("Show Modifier Button 1 Layers", CVAR_INPUT_VIEWER("Mod1"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, false); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod1"), 0)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod1OutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - // gInputViewer.Mod2 - UIWidgets::EnhancementCheckbox("Show Modifier Button 2 Layers", CVAR_INPUT_VIEWER("Mod2"), false, "", - UIWidgets::CheckboxGraphics::Checkmark, false); - if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) { - ImGui::Indent(); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod2OutlineMode"), buttonOutlineOptionsVerbose, - BUTTON_OUTLINE_NOT_PRESSED); - ImGui::Unindent(); - } - - UIWidgets::PaddedSeparator(true, true); - } - - if (ImGui::CollapsingHeader("Analog Stick")) { - // gInputViewer.AnalogStick.VisibilityMode - UIWidgets::PaddedText("Analog Stick Visibility", true, false); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions, - STICK_MODE_ALWAYS_SHOWN); - UIWidgets::Tooltip( - "Determines the conditions under which the moving layer of the analog stick texture is visible."); - - // gInputViewer.AnalogStick.OutlineMode - UIWidgets::PaddedText("Analog Stick Outline/Background Visibility", true, false); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), stickModeOptions, - STICK_MODE_ALWAYS_SHOWN); - UIWidgets::Tooltip( - "Determines the conditions under which the analog stick outline/background texture is visible."); + if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) { + // gInputViewer.RightStick.VisibilityMode + UIWidgets::PaddedText("Right Stick Visibility", true, false); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions, + STICK_MODE_HIDDEN_IN_DEADZONE); + UIWidgets::Tooltip( + "Determines the conditions under which the moving layer of the right stick texture is visible."); + + // gInputViewer.RightStick.OutlineMode + UIWidgets::PaddedText("Right Stick Outline/Background Visibility", true, false); + UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions, + STICK_MODE_HIDDEN_IN_DEADZONE); + UIWidgets::Tooltip( + "Determines the conditions under which the right stick outline/background texture is visible."); + + // gInputViewer.RightStick.Movement + UIWidgets::EnhancementSliderInt("Right Stick Movement: %dpx", "##RightMovement", + CVAR_INPUT_VIEWER("RightStick.Movement"), 0, 200, "", 7, true); + UIWidgets::Tooltip( + "Sets the distance to move the right stick in the input viewer. Useful for custom input viewers."); + UIWidgets::PaddedSeparator(true, true); + } - // gInputViewer.AnalogStick.Movement - UIWidgets::EnhancementSliderInt("Analog Stick Movement: %dpx", "##AnalogMovement", - CVAR_INPUT_VIEWER("AnalogStick.Movement"), 0, 200, "", 12, true); - UIWidgets::Tooltip( - "Sets the distance to move the analog stick in the input viewer. Useful for custom input viewers."); + if (ImGui::CollapsingHeader("Analog Angle Values")) { + // gAnalogAngles + UIWidgets::EnhancementCheckbox("Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled")); + UIWidgets::Tooltip("Displays analog stick angle values in the input viewer"); + if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0)) { + // gInputViewer.AnalogAngles.TextColor + if (ImGui::ColorEdit4("Text Color", (float*)&textColor)) { + CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), vec2Color(textColor)); + } + // gAnalogAngleScale + UIWidgets::EnhancementSliderFloat("Angle Text Scale: %.2f%%", "##AnalogAngleScale", + CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 0.1f, 5.0f, "", 1.0f, true, true); + // gInputViewer.AnalogAngles.Offset + UIWidgets::EnhancementSliderInt("Angle Text Offset: %dpx", "##AnalogAngleOffset", + CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0, 400, "", 0, true); UIWidgets::PaddedSeparator(true, true); - } - - if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) { - // gInputViewer.RightStick.VisibilityMode - UIWidgets::PaddedText("Right Stick Visibility", true, false); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions, - STICK_MODE_HIDDEN_IN_DEADZONE); - UIWidgets::Tooltip( - "Determines the conditions under which the moving layer of the right stick texture is visible."); - - // gInputViewer.RightStick.OutlineMode - UIWidgets::PaddedText("Right Stick Outline/Background Visibility", true, false); - UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions, - STICK_MODE_HIDDEN_IN_DEADZONE); + // gInputViewer.AnalogAngles.Range1.Enabled + UIWidgets::EnhancementCheckbox("Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled")); UIWidgets::Tooltip( - "Determines the conditions under which the right stick outline/background texture is visible."); - - // gInputViewer.RightStick.Movement - UIWidgets::EnhancementSliderInt("Right Stick Movement: %dpx", "##RightMovement", - CVAR_INPUT_VIEWER("RightStick.Movement"), 0, 200, "", 7, true); - UIWidgets::Tooltip( - "Sets the distance to move the right stick in the input viewer. Useful for custom input viewers."); - UIWidgets::PaddedSeparator(true, true); - } - - if (ImGui::CollapsingHeader("Analog Angle Values")) { - // gAnalogAngles - UIWidgets::EnhancementCheckbox("Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled")); - UIWidgets::Tooltip("Displays analog stick angle values in the input viewer"); - if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0)) { - // gInputViewer.AnalogAngles.TextColor - if (ImGui::ColorEdit4("Text Color", (float*)&textColor)) { - CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), vec2Color(textColor)); - } - // gAnalogAngleScale - UIWidgets::EnhancementSliderFloat("Angle Text Scale: %.2f%%", "##AnalogAngleScale", - CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 0.1f, 5.0f, "", 1.0f, true, true); - // gInputViewer.AnalogAngles.Offset - UIWidgets::EnhancementSliderInt("Angle Text Offset: %dpx", "##AnalogAngleOffset", - CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0, 400, "", 0, true); - UIWidgets::PaddedSeparator(true, true); - // gInputViewer.AnalogAngles.Range1.Enabled - UIWidgets::EnhancementCheckbox("Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled")); - UIWidgets::Tooltip( - "Highlights the angle value text when the analog stick is in ESS position (on flat ground)"); - if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0)) { - // gInputViewer.AnalogAngles.Range1.Color - if (ImGui::ColorEdit4("ESS Color", (float*)&range1Color)) { - CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color)); - } + "Highlights the angle value text when the analog stick is in ESS position (on flat ground)"); + if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0)) { + // gInputViewer.AnalogAngles.Range1.Color + if (ImGui::ColorEdit4("ESS Color", (float*)&range1Color)) { + CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color)); } + } - UIWidgets::PaddedSeparator(true, true); - // gInputViewer.AnalogAngles.Range2.Enabled - UIWidgets::EnhancementCheckbox("Highlight Walking Speed Angles", - CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled")); - UIWidgets::Tooltip("Highlights the angle value text when the analog stick is at an angle that would " - "produce a walking speed (on flat ground)\n\n" - "Useful for 1.0 Empty Jumpslash Quick Put Away"); - if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0)) { - // gInputViewer.AnalogAngles.Range2.Color - if (ImGui::ColorEdit4("Walking Speed Color", (float*)&range2Color)) { - CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color)); - } + UIWidgets::PaddedSeparator(true, true); + // gInputViewer.AnalogAngles.Range2.Enabled + UIWidgets::EnhancementCheckbox("Highlight Walking Speed Angles", + CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled")); + UIWidgets::Tooltip("Highlights the angle value text when the analog stick is at an angle that would " + "produce a walking speed (on flat ground)\n\n" + "Useful for 1.0 Empty Jumpslash Quick Put Away"); + if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0)) { + // gInputViewer.AnalogAngles.Range2.Color + if (ImGui::ColorEdit4("Walking Speed Color", (float*)&range2Color)) { + CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color)); } } } - - ImGui::End(); } } diff --git a/soh/soh/Enhancements/controls/InputViewer.h b/soh/soh/Enhancements/controls/InputViewer.h index 3e1e9c98798..a4b1cc44fce 100644 --- a/soh/soh/Enhancements/controls/InputViewer.h +++ b/soh/soh/Enhancements/controls/InputViewer.h @@ -21,6 +21,7 @@ class InputViewer : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; + void Draw() override; void InitElement() override {}; void DrawElement() override; void UpdateElement() override {}; @@ -28,8 +29,6 @@ class InputViewer : public Ship::GuiWindow { InputViewer(); ~InputViewer(); - void Draw(); - private: void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode); }; @@ -44,6 +43,4 @@ class InputViewerSettingsWindow : public Ship::GuiWindow { InputViewerSettingsWindow(); ~InputViewerSettingsWindow(); - - void Draw(); }; diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index f4f344b49eb..deb4ce8f5f6 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1688,12 +1688,6 @@ static const char* colorSchemes[2] = { }; void CosmeticsEditorWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(550, 520), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Cosmetics Editor", &mIsVisible)) { - ImGui::End(); - return; - } - ImGui::Text("Color Scheme"); ImGui::SameLine(); UIWidgets::EnhancementCombobox(CVAR_COSMETIC("DefaultColorScheme"), colorSchemes, COLORSCHEME_N64); @@ -1812,7 +1806,6 @@ void CosmeticsEditorWindow::DrawElement() { } ImGui::EndTabBar(); } - ImGui::End(); } void RegisterOnLoadGameHook() { diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index ad51f1e4b01..f1f3ac76b0e 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -1590,6 +1590,5 @@ void DebugConsole_Init(void) { {"group_name", Ship::ArgumentType::TEXT, true}, }}); - CVarSave(); - CVarLoad(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index db0585b9913..5b23c1876e5 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.cpp +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -20,11 +20,6 @@ void MessageViewer::InitElement() { } void MessageViewer::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Custom Message Debugger", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } ImGui::Text("Table ID"); ImGui::SameLine(); ImGui::InputText("##TableID", mTableIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum); @@ -74,7 +69,6 @@ void MessageViewer::DrawElement() { if (ImGui::Button("Display Message##CustomMessage")) { mDisplayCustomMessageClicked = true; } - ImGui::End(); // ReSharper restore CppDFAUnreachableCode } diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index 3e4d271a827..84ecd5ff0ea 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -925,12 +925,6 @@ void ActorViewer_AddTagForAllActors() { } void ActorViewerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Actor Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - static Actor* display; static Actor empty{}; static Actor* fetch = NULL; @@ -1235,8 +1229,6 @@ void ActorViewerWindow::DrawElement() { actors.clear(); } } - - ImGui::End(); } void ActorViewerWindow::InitElement() { diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 3b5b7aa4758..8ce5f8b501a 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -53,11 +53,6 @@ static std::vector sphereVtx; // Draws the ImGui window for the collision viewer void ColViewerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Collision Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } UIWidgets::EnhancementCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled")); UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), ColRenderSettingNames, COLVIEW_DISABLED); @@ -95,8 +90,6 @@ void ColViewerWindow::DrawElement() { } else { UIWidgets::InsertHelpHoverText(colorHelpText); } - - ImGui::End(); } // Calculates the normal for a triangle at the 3 specified points diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 0017f9f7dc0..46f14205450 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1320,7 +1320,16 @@ void DrawEquipmentTab() { "Giant (500)", }; // only display Tycoon wallet if you're in a save file that would allow it. - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS) { + if ( + IS_RANDO && + !( + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF || + ( + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS + ) + ) + ) { const std::string walletName = "Tycoon (999)"; walletNamesImpl.push_back(walletName); } @@ -1777,12 +1786,6 @@ void DrawPlayerTab() { } void SaveEditorWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Save Editor", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - if (ImGui::BeginTabBar("SaveContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { if (ImGui::BeginTabItem("Info")) { DrawInfoTab(); @@ -1816,8 +1819,6 @@ void SaveEditorWindow::DrawElement() { ImGui::EndTabBar(); } - - ImGui::End(); } void SaveEditorWindow::InitElement() { diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index 790f426dfb6..42b005a8c2d 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -90,12 +90,6 @@ void PerformDisplayListSearch() { } void DLViewerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Display List Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - // Debounce the search field as listing otr files is expensive if (ImGui::InputText("Search Display Lists", searchString, ARRAY_COUNT(searchString))) { doSearch = true; @@ -122,7 +116,6 @@ void DLViewerWindow::DrawElement() { } if (activeDisplayList == "") { - ImGui::End(); return; } @@ -131,7 +124,6 @@ void DLViewerWindow::DrawElement() { if (res->GetInitData()->Type != static_cast(LUS::ResourceType::DisplayList)) { ImGui::Text("Resource type is not a Display List. Please choose another."); - ImGui::End(); return; } @@ -325,11 +317,8 @@ void DLViewerWindow::DrawElement() { } } catch (const std::exception& e) { ImGui::Text("Error displaying DL instructions."); - ImGui::End(); return; } - - ImGui::End(); } void DLViewerWindow::InitElement() { diff --git a/soh/soh/Enhancements/debugger/hookDebugger.cpp b/soh/soh/Enhancements/debugger/hookDebugger.cpp new file mode 100644 index 00000000000..b31ddc3966f --- /dev/null +++ b/soh/soh/Enhancements/debugger/hookDebugger.cpp @@ -0,0 +1,111 @@ +#include "hookDebugger.h" +#include "../game-interactor/GameInteractor.h" +#include "../../UIWidgets.hpp" +#include +#include + +static std::unordered_map> hookData; + +const ImVec4 grey = ImVec4(0.75, 0.75, 0.75, 1); +const ImVec4 yellow = ImVec4(1, 1, 0, 1); +const ImVec4 red = ImVec4(1, 0, 0, 1); + +void DrawHookRegisteringInfos(const char* hookName) { + if (hookData[hookName].size() == 0) { + ImGui::TextColored(grey, "No hooks found"); + return; + } + + if (ImGui::BeginTable( + ("Table##" + std::string(hookName)).c_str(), + 4, + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit + )) { + ImGui::TableSetupColumn("Id"); + ImGui::TableSetupColumn("Type"); + ImGui::TableSetupColumn("Registration Info"); + //ImGui::TableSetupColumn("Stub"); + ImGui::TableSetupColumn("Number of Calls"); + ImGui::TableHeadersRow(); + for (auto& [id, hookInfo] : hookData[hookName]) { + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + ImGui::Text("%d", id); + + ImGui::TableNextColumn(); + switch (hookInfo.registering.type) { + case HOOK_TYPE_NORMAL: + ImGui::Text("Normal"); + break; + case HOOK_TYPE_ID: + ImGui::Text("Id"); + break; + case HOOK_TYPE_PTR: + ImGui::Text("Ptr"); + break; + case HOOK_TYPE_FILTER: + ImGui::Text("Filter"); + break; + default: + ImGui::TextColored(red, "[UNKNOWN]"); + break; + } + + ImGui::TableNextColumn(); + if (hookInfo.registering.valid) { + ImGui::Text("%s(%d:%d) %s", hookInfo.registering.file, hookInfo.registering.line, hookInfo.registering.column, hookInfo.registering.function); + } else { + ImGui::TextColored(yellow, "[Unavaliable]"); + } + + //TODO: not currently possible + /* + ImGui::TableNextColumn(); + + ImGui::BeginDisabled(); + + bool stubButtonPressed = ImGui::Button(("Stub##" + std::to_string(id)).c_str()); + UIWidgets::SetLastItemHoverText("Stub this hook.\nThis is not possible to automatically undo."); + + if (stubButtonPressed) { + //stub + } + + ImGui::EndDisabled(); + */ + + ImGui::TableNextColumn(); + ImGui::Text("%d", hookInfo.calls); + } + ImGui::EndTable(); + } +} + +void HookDebuggerWindow::DrawElement() { +#ifndef __cpp_lib_source_location + ImGui::TextColored( + yellow, + "Some features of the Hook Debugger are unavaliable because SoH was compiled " + "without \"\" support " + "(\"__cpp_lib_source_location\" not defined in \"\")." + ); +#endif + + for (auto& [hookName, _] : hookData) { + if (ImGui::TreeNode(hookName)) { + DrawHookRegisteringInfos(hookName); + ImGui::TreePop(); + } + } +} + +void HookDebuggerWindow::UpdateElement() { + hookData.clear(); + + #define DEFINE_HOOK(name, _) hookData.insert({#name, GameInteractor::Instance->GetHookData()}); + + #include "../game-interactor/GameInteractor_HookTable.h" + + #undef DEFINE_HOOK +} \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/hookDebugger.h b/soh/soh/Enhancements/debugger/hookDebugger.h new file mode 100644 index 00000000000..90e6886b5ec --- /dev/null +++ b/soh/soh/Enhancements/debugger/hookDebugger.h @@ -0,0 +1,10 @@ +#include + +class HookDebuggerWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override {}; + void DrawElement() override; + void UpdateElement() override; +}; diff --git a/soh/soh/Enhancements/debugger/performanceTimer.cpp b/soh/soh/Enhancements/debugger/performanceTimer.cpp new file mode 100644 index 00000000000..f52a8efaca0 --- /dev/null +++ b/soh/soh/Enhancements/debugger/performanceTimer.cpp @@ -0,0 +1,19 @@ +#pragma once + +#include "performanceTimer.h" + +void StartPerformanceTimer(TimerID timer){ + timeStarted[timer] = std::chrono::high_resolution_clock::now(); +} + +void StopPerformanceTimer(TimerID timer){ + totalTimes[timer] += (std::chrono::high_resolution_clock::now() - timeStarted[timer]); +} + +std::chrono::duration GetPerformanceTimer(TimerID timer){ + return totalTimes[timer]; +} + +void ResetPerformanceTimers(){ + totalTimes = {}; +} \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/performanceTimer.h b/soh/soh/Enhancements/debugger/performanceTimer.h new file mode 100644 index 00000000000..f4bc8f017c7 --- /dev/null +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +typedef enum { + PT_WHOLE_SEED, + PT_LOGIC_RESET, + PT_REGION_RESET, + PT_SPOILER_LOG, + PT_ENTRANCE_SHUFFLE, + PT_SHOPSANITY, + PT_OWN_DUNGEON, + PT_LIMITED_CHECKS, + PT_ADVANCEMENT_ITEMS, + PT_REMAINING_ITEMS, + PT_PLAYTHROUGH_GENERATION, + PT_PARE_DOWN_PLAYTHROUGH, + PT_WOTH, + PT_FOOLISH, + PT_OVERRIDES, + PT_HINTS, + PT_EVENT_ACCESS, + PT_TOD_ACCESS, + PT_ENTRANCE_LOGIC, + PT_LOCATION_LOGIC, + PT_MAX +} TimerID; + +void StartPerformanceTimer(TimerID timer); +void StopPerformanceTimer(TimerID timer); +std::chrono::duration GetPerformanceTimer(TimerID timer); +void ResetPerformanceTimers(); +static std::array, PT_MAX> totalTimes = {}; +static std::array timeStarted = {}; + diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index 100ad694384..c03be8ee1c7 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -104,12 +104,6 @@ extern "C" void ValueViewer_Draw(GfxPrint* printer) { } void ValueViewerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Value Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - UIWidgets::PaddedEnhancementCheckbox("Enable Printing", CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting")); ImGui::BeginGroup(); @@ -214,8 +208,6 @@ void ValueViewerWindow::DrawElement() { } ImGui::EndGroup(); } - - ImGui::End(); } void ValueViewerWindow::InitElement() { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 3523fa4057f..70fd7026724 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -78,6 +78,8 @@ typedef enum { // Vanilla condition: INFTABLE_GREETED_BY_SARIA VB_NOT_BE_GREETED_BY_SARIA, // Opt: *EnMd + VB_MIDO_SPAWN, + // Opt: *EnMd // Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION VB_MOVE_MIDO_IN_KOKIRI_FOREST, // Opt: *EnMd @@ -139,6 +141,9 @@ typedef enum { // Opt: *EnItem00 // Vanilla condition: Flags_GetCollectible(play, this->collectibleFlag) VB_ITEM00_DESPAWN, + // Opt: *ItemBHeart + // Vanilla condition: Flags_GetCollectible(play, 0x1F) + VB_ITEM_B_HEART_DESPAWN, // Opt: *EnTk // Vanilla condition: gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD VB_DAMPE_IN_GRAVEYARD_DESPAWN, @@ -242,6 +247,8 @@ typedef enum { ``` */ VB_DRAW_AMMO_COUNT, + VB_FREEZE_LINK_FOR_BLOCK_THROW, + VB_MOVE_THROWN_ACTOR, /*** Play Cutscenes ***/ @@ -284,6 +291,7 @@ typedef enum { VB_PLAY_RAINBOW_BRIDGE_CS, // Opt: *EnBox VB_PLAY_SLOW_CHEST_CS, + VB_PLAY_THROW_ANIMATION, /*** Give Items ***/ @@ -413,6 +421,11 @@ typedef enum { // Vanilla condition: true VB_PHANTOM_GANON_DEATH_SCENE, VB_NABOORU_KNUCKLE_DEATH_SCENE, + + /*** Fishsanity ***/ + // Vanilla condition: Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT + // Opt: *Actor + VB_BOTTLE_ACTOR, } GIVanillaBehavior; #ifdef __cplusplus @@ -450,6 +463,12 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state); #include #include #include +#include +#ifdef __cpp_lib_source_location +#include +#else +#pragma message("Compiling without support, the Hook Debugger will not be avaliable") +#endif #ifdef ENABLE_REMOTE_CONTROL #include @@ -458,11 +477,40 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state); typedef uint32_t HOOK_ID; -#define DEFINE_HOOK(name, args) \ - struct name { \ - typedef std::function fn; \ - typedef std::function filter; \ - } +enum HookType { + HOOK_TYPE_NORMAL, + HOOK_TYPE_ID, + HOOK_TYPE_PTR, + HOOK_TYPE_FILTER, +}; + +struct HookRegisteringInfo { + bool valid; + const char* file; + std::uint_least32_t line; + std::uint_least32_t column; + const char* function; + HookType type; + + HookRegisteringInfo() : valid(false), file("unknown file"), line(0), column(0), function("unknown function"), type(HOOK_TYPE_NORMAL) {} + + HookRegisteringInfo(const char* _file, std::uint_least32_t _line, std::uint_least32_t _column, const char* _function, HookType _type) : + valid(true), file(_file), line(_line), column(_column), function(_function), type(_type) {} +}; + +struct HookInfo { + uint32_t calls; + HookRegisteringInfo registering; + + HookInfo() : calls(0), registering(HookRegisteringInfo{}) {} + HookInfo(HookRegisteringInfo _registering) : calls(0), registering(_registering) {} +}; + +#ifdef __cpp_lib_source_location +#define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{location.file_name(), location.line(), location.column(), location.function_name(), type} +#else +#define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{} +#endif #define REGISTER_VB_SHOULD(flag, body) \ GameInteractor::Instance->RegisterGameHookForID(flag, [](GIVanillaBehavior _, bool* should, void* opt) body) @@ -471,7 +519,7 @@ class GameInteractor { public: static GameInteractor* Instance; - // Gsme State + // Game State class State { public: static bool NoUIActive; @@ -524,7 +572,11 @@ class GameInteractor { inline static std::unordered_map> functionsForID; inline static std::unordered_map> functionsForPtr; inline static std::unordered_map> functionsForFilter; + + //Used for the hook debugger + inline static std::unordered_map hookData; }; + template struct HooksToUnregister { inline static std::vector hooks; inline static std::vector hooksForID; @@ -532,50 +584,74 @@ class GameInteractor { inline static std::vector hooksForFilter; }; + template std::unordered_map GetHookData() { + return RegisteredGameHooks::hookData; + } + // General Hooks - template HOOK_ID RegisterGameHook(typename H::fn h) { + template HOOK_ID RegisterGameHook( + typename H::fn h +#ifdef __cpp_lib_source_location + , const std::source_location location = std::source_location::current() +#endif + ) { + // Ensure hook id is unique and not 0, which is reserved for invalid hooks if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1; while (RegisteredGameHooks::functions.find(this->nextHookId) != RegisteredGameHooks::functions.end()) { this->nextHookId++; } RegisteredGameHooks::functions[this->nextHookId] = h; + RegisteredGameHooks::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_NORMAL)}; return this->nextHookId++; } + template void UnregisterGameHook(HOOK_ID hookId) { if (hookId == 0) return; HooksToUnregister::hooks.push_back(hookId); } + template void ExecuteHooks(Args&&... args) { for (auto& hookId : HooksToUnregister::hooks) { RegisteredGameHooks::functions.erase(hookId); + RegisteredGameHooks::hookData.erase(hookId); } HooksToUnregister::hooks.clear(); for (auto& hook : RegisteredGameHooks::functions) { hook.second(std::forward(args)...); + RegisteredGameHooks::hookData[hook.first].calls += 1; } } // ID based Hooks - template HOOK_ID RegisterGameHookForID(int32_t id, typename H::fn h) { + template HOOK_ID RegisterGameHookForID( + int32_t id, typename H::fn h +#ifdef __cpp_lib_source_location + , const std::source_location location = std::source_location::current() +#endif + ) { if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1; while (RegisteredGameHooks::functionsForID[id].find(this->nextHookId) != RegisteredGameHooks::functionsForID[id].end()) { this->nextHookId++; } RegisteredGameHooks::functionsForID[id][this->nextHookId] = h; + RegisteredGameHooks::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_ID)}; return this->nextHookId++; } + template void UnregisterGameHookForID(HOOK_ID hookId) { if (hookId == 0) return; HooksToUnregister::hooksForID.push_back(hookId); } + template void ExecuteHooksForID(int32_t id, Args&&... args) { for (auto& hookId : HooksToUnregister::hooksForID) { for (auto it = RegisteredGameHooks::functionsForID[id].begin(); it != RegisteredGameHooks::functionsForID[id].end(); ) { if (it->first == hookId) { it = RegisteredGameHooks::functionsForID[id].erase(it); HooksToUnregister::hooksForID.erase(std::remove(HooksToUnregister::hooksForID.begin(), HooksToUnregister::hooksForID.end(), hookId), HooksToUnregister::hooksForID.end()); + RegisteredGameHooks::hookData.erase(hookId); } else { ++it; } @@ -583,29 +659,39 @@ class GameInteractor { } for (auto& hook : RegisteredGameHooks::functionsForID[id]) { hook.second(std::forward(args)...); + RegisteredGameHooks::hookData[hook.first].calls += 1; } } // PTR based Hooks - template HOOK_ID RegisterGameHookForPtr(uintptr_t ptr, typename H::fn h) { + template HOOK_ID RegisterGameHookForPtr( + uintptr_t ptr, typename H::fn h +#ifdef __cpp_lib_source_location + , const std::source_location location = std::source_location::current() +#endif + ) { if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1; while (RegisteredGameHooks::functionsForPtr[ptr].find(this->nextHookId) != RegisteredGameHooks::functionsForPtr[ptr].end()) { this->nextHookId++; } RegisteredGameHooks::functionsForPtr[ptr][this->nextHookId] = h; + RegisteredGameHooks::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_PTR)}; return this->nextHookId++; } + template void UnregisterGameHookForPtr(HOOK_ID hookId) { if (hookId == 0) return; HooksToUnregister::hooksForPtr.push_back(hookId); } + template void ExecuteHooksForPtr(uintptr_t ptr, Args&&... args) { for (auto& hookId : HooksToUnregister::hooksForPtr) { for (auto it = RegisteredGameHooks::functionsForPtr[ptr].begin(); it != RegisteredGameHooks::functionsForPtr[ptr].end(); ) { if (it->first == hookId) { it = RegisteredGameHooks::functionsForPtr[ptr].erase(it); HooksToUnregister::hooksForPtr.erase(std::remove(HooksToUnregister::hooksForPtr.begin(), HooksToUnregister::hooksForPtr.end(), hookId), HooksToUnregister::hooksForPtr.end()); + RegisteredGameHooks::hookData.erase(hookId); } else { ++it; } @@ -613,31 +699,42 @@ class GameInteractor { } for (auto& hook : RegisteredGameHooks::functionsForPtr[ptr]) { hook.second(std::forward(args)...); + RegisteredGameHooks::hookData[hook.first].calls += 1; } } // Filter based Hooks - template HOOK_ID RegisterGameHookForFilter(typename H::filter f, typename H::fn h) { + template HOOK_ID RegisterGameHookForFilter( + typename H::filter f, typename H::fn h +#ifdef __cpp_lib_source_location + , const std::source_location location = std::source_location::current() +#endif + ) { if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1; while (RegisteredGameHooks::functionsForFilter.find(this->nextHookId) != RegisteredGameHooks::functionsForFilter.end()) { this->nextHookId++; } RegisteredGameHooks::functionsForFilter[this->nextHookId] = std::make_pair(f, h); + RegisteredGameHooks::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_FILTER)}; return this->nextHookId++; } + template void UnregisterGameHookForFilter(HOOK_ID hookId) { if (hookId == 0) return; HooksToUnregister::hooksForFilter.push_back(hookId); } + template void ExecuteHooksForFilter(Args&&... args) { for (auto& hookId : HooksToUnregister::hooksForFilter) { RegisteredGameHooks::functionsForFilter.erase(hookId); + RegisteredGameHooks::hookData.erase(hookId); } HooksToUnregister::hooksForFilter.clear(); for (auto& hook : RegisteredGameHooks::functionsForFilter) { if (hook.second.first(std::forward(args)...)) { hook.second.second(std::forward(args)...); + RegisteredGameHooks::hookData[hook.first].calls += 1; } } } @@ -664,59 +761,15 @@ class GameInteractor { } }; - DEFINE_HOOK(OnLoadGame, (int32_t fileNum)); - DEFINE_HOOK(OnExitGame, (int32_t fileNum)); - DEFINE_HOOK(OnGameFrameUpdate, ()); - DEFINE_HOOK(OnItemReceive, (GetItemEntry itemEntry)); - DEFINE_HOOK(OnSaleEnd, (GetItemEntry itemEntry)); - DEFINE_HOOK(OnTransitionEnd, (int16_t sceneNum)); - DEFINE_HOOK(OnSceneInit, (int16_t sceneNum)); - DEFINE_HOOK(OnSceneFlagSet, (int16_t sceneNum, int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnSceneFlagUnset, (int16_t sceneNum, int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnFlagSet, (int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnSceneSpawnActors, ()); - DEFINE_HOOK(OnPlayerUpdate, ()); - DEFINE_HOOK(OnOcarinaSongAction, ()); - DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price)); - DEFINE_HOOK(OnActorInit, (void* actor)); - DEFINE_HOOK(OnActorUpdate, (void* actor)); - DEFINE_HOOK(OnActorKill, (void* actor)); - DEFINE_HOOK(OnEnemyDefeat, (void* actor)); - DEFINE_HOOK(OnPlayerBonk, ()); - DEFINE_HOOK(OnPlayDestroy, ()); - DEFINE_HOOK(OnPlayDrawEnd, ()); - - DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, void* opt)); - - DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); - DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); - DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); - - DEFINE_HOOK(OnDialogMessage, ()); - DEFINE_HOOK(OnPresentTitleCard, ()); - DEFINE_HOOK(OnInterfaceUpdate, ()); - DEFINE_HOOK(OnKaleidoscopeUpdate, (int16_t inDungeonScene)); - - DEFINE_HOOK(OnPresentFileSelect, ()); - DEFINE_HOOK(OnUpdateFileSelectSelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileCopySelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileEraseSelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, (uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileAudioSelection, (uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileTargetSelection, (uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileLanguageSelection, (uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileQuestSelection, (uint8_t questIndex)); - DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, (uint8_t optionIndex, uint8_t optionValue)); - DEFINE_HOOK(OnUpdateFileNameSelection, (int16_t charCode)); - - DEFINE_HOOK(OnSetGameLanguage, ()); - - DEFINE_HOOK(OnFileDropped, (std::string filePath)); - DEFINE_HOOK(OnAssetAltChange, ()); - DEFINE_HOOK(OnKaleidoUpdate, ()); +#define DEFINE_HOOK(name, args) \ + struct name { \ + typedef std::function fn; \ + typedef std::function filter; \ + } + +#include "GameInteractor_HookTable.h" + +#undef DEFINE_HOOK // Helpers static bool IsSaveLoaded(bool allowDbgSave = false); @@ -777,5 +830,7 @@ class GameInteractor { #endif }; +#undef GET_CURRENT_REGISTERING_INFO + #endif /* __cplusplus */ #endif /* GameInteractor_h */ diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h new file mode 100644 index 00000000000..a3fc284eef9 --- /dev/null +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -0,0 +1,57 @@ +/** + * Hook Table + * + * DEFINE_HOOK arguments: + * - Argument 1: Name of the hook + * - Argument 2: Function type that the hook uses + */ +DEFINE_HOOK(OnLoadGame, (int32_t fileNum)); +DEFINE_HOOK(OnExitGame, (int32_t fileNum)); +DEFINE_HOOK(OnGameFrameUpdate, ()); +DEFINE_HOOK(OnItemReceive, (GetItemEntry itemEntry)); +DEFINE_HOOK(OnSaleEnd, (GetItemEntry itemEntry)); +DEFINE_HOOK(OnTransitionEnd, (int16_t sceneNum)); +DEFINE_HOOK(OnSceneInit, (int16_t sceneNum)); +DEFINE_HOOK(OnSceneFlagSet, (int16_t sceneNum, int16_t flagType, int16_t flag)); +DEFINE_HOOK(OnSceneFlagUnset, (int16_t sceneNum, int16_t flagType, int16_t flag)); +DEFINE_HOOK(OnFlagSet, (int16_t flagType, int16_t flag)); +DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag)); +DEFINE_HOOK(OnSceneSpawnActors, ()); +DEFINE_HOOK(OnPlayerUpdate, ()); +DEFINE_HOOK(OnOcarinaSongAction, ()); +DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price)); +DEFINE_HOOK(OnActorInit, (void* actor)); +DEFINE_HOOK(OnActorUpdate, (void* actor)); +DEFINE_HOOK(OnActorKill, (void* actor)); +DEFINE_HOOK(OnEnemyDefeat, (void* actor)); +DEFINE_HOOK(OnPlayerBonk, ()); +DEFINE_HOOK(OnPlayDestroy, ()); +DEFINE_HOOK(OnPlayDrawEnd, ()); +DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, void* opt)); +DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); +DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); +DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); + +DEFINE_HOOK(OnDialogMessage, ()); +DEFINE_HOOK(OnPresentTitleCard, ()); +DEFINE_HOOK(OnInterfaceUpdate, ()); +DEFINE_HOOK(OnKaleidoscopeUpdate, (int16_t inDungeonScene)); + +DEFINE_HOOK(OnPresentFileSelect, ()); +DEFINE_HOOK(OnUpdateFileSelectSelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileCopySelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileEraseSelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, (uint16_t optionIndex)); +DEFINE_HOOK(OnUpdateFileAudioSelection, (uint8_t optionIndex)); +DEFINE_HOOK(OnUpdateFileTargetSelection, (uint8_t optionIndex)); +DEFINE_HOOK(OnUpdateFileLanguageSelection, (uint8_t optionIndex)); +DEFINE_HOOK(OnUpdateFileQuestSelection, (uint8_t questIndex)); +DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, (uint8_t optionIndex, uint8_t optionValue)); +DEFINE_HOOK(OnUpdateFileNameSelection, (int16_t charCode)); + +DEFINE_HOOK(OnSetGameLanguage, ()); +DEFINE_HOOK(OnFileDropped, (std::string filePath)); +DEFINE_HOOK(OnAssetAltChange, ()); +DEFINE_HOOK(OnKaleidoUpdate, ()); \ No newline at end of file diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 61eb88a6f16..82a4b3b6e17 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -437,7 +437,13 @@ void DrawGameplayStatsHeader() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); ImGui::BeginTable("gameplayStatsHeader", 1, ImGuiTableFlags_BordersOuter); ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); - GameplayStatsRow("Build Version:", (char*) gBuildVersion); + //if tag is empty (not a release build) + if (gGitCommitTag[0] == 0) { + GameplayStatsRow("Git Branch:", (char*)gGitBranch); + GameplayStatsRow("Git Commit Hash:", (char*)gGitCommitHash); + } else { + GameplayStatsRow("Build Version:", (char*)gBuildVersion); + } if (gSaveContext.sohStats.rtaTiming) { GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE); } else { @@ -619,12 +625,6 @@ void DrawGameplayStatsOptionsTab() { } void GameplayStatsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(480, 550), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Gameplay Stats", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - DrawGameplayStatsHeader(); if (ImGui::BeginTabBar("Stats", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { @@ -648,8 +648,6 @@ void GameplayStatsWindow::DrawElement() { } ImGui::Text("Note: Gameplay stats are saved to the current file and will be\nlost if you quit without saving."); - - ImGui::End(); } void InitStats(bool isDebug) { gSaveContext.sohStats.heartPieces = isDebug ? 8 : 0; diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 8b3adca0f35..a8141ca8158 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -6,7 +6,6 @@ #include "soh/Enhancements/boss-rush/BossRushTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/3drando/random.hpp" -#include "soh/Enhancements/randomizer/fishsanity.h" #include "soh/Enhancements/cosmetics/authenticGfxPatches.h" #include #include "soh/Enhancements/nametag.h" @@ -1545,156 +1544,6 @@ void RegisterNoWallet() { }); } -void RegisterFishsanity() { - static s16 fishGroupCounter = 0; - - // Initialization on load - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - if (!IS_RANDO) { - return; - } - OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); - }); - - // Initialize actors for fishsanity - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - if (!IS_RANDO) { - return; - } - - Actor* actor = static_cast(refActor); - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - FishIdentity fish; - - if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - // Set fish ID for ZD fish - if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && actor->params == -1) { - actor->params ^= fishGroupCounter++; - } - - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - // Create effect for uncaught fish - if (Rando::Fishsanity::IsFish(&fish) && !Flags_GetRandomizerInf(fish.randomizerInf)) { - actor->shape.shadowDraw = Fishsanity_DrawEffShadow; - } - return; - } - - if (actor->id == ACTOR_FISHING && gPlayState->sceneNum == SCENE_FISHING_POND && actor->params >= 100 && - actor->params <= 117 && fs->GetPondFishShuffled()) { - // Initialize pond fish for fishsanity - // Initialize fishsanity metadata on this actor - Fishing* fishActor = static_cast(refActor); - fishActor->fishsanityParams = actor->params; - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - - // With every pond fish shuffled, caught fish will not spawn unless all fish have been caught. - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT) > 16 && - !fs->GetPondCleared()) { - // Create effect for uncaught fish - if (!Flags_GetRandomizerInf(fish.randomizerInf)) { - actor->shape.shadowDraw = Fishsanity_DrawEffShadow; - } - } - } - - }); - - // Update fishsanity when a fish is caught - GameInteractor::Instance->RegisterGameHook([](int16_t flagType, int16_t flag) { - if (!IS_RANDO || flagType != FLAG_RANDOMIZER_INF) { - return; - } - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)flag); - FishsanityCheckType fsType = Rando::Fishsanity::GetCheckType(rc); - if (fsType == FSC_NONE) { - return; - } - - // When a pond fish is caught, advance the pond. - if (fsType == FSC_POND) { - OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); - } - }); - - // Award fishing pond checks - GameInteractor::Instance->RegisterGameHook([]() { - if (!IS_RANDO || GameInteractor::IsGameplayPaused() || !gPlayState) { - return; - } - - Player* player = GET_PLAYER(gPlayState); - if (Player_InBlockingCsMode(gPlayState, player)) { - return; - } - - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - if (!fs->GetPondFishShuffled()) { - return; - } - - FishIdentity pending = fs->GetPendingFish(); - if (!Rando::Fishsanity::IsFish(&pending)) { // No fish currently pending - return; - } - - // Award fish - GetItemEntry gi = OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(pending.randomizerCheck, GI_NONE); - Flags_SetRandomizerInf(pending.randomizerInf); - GiveItemEntryWithoutActor(gPlayState, gi); - fs->SetPendingFish(NULL); - }); - - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - if (!IS_RANDO || (gPlayState->sceneNum != SCENE_GROTTOS && gPlayState->sceneNum != SCENE_ZORAS_DOMAIN && gPlayState->sceneNum != SCENE_FISHING_POND)) { - return; - } - - Actor* actor = static_cast(refActor); - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - - // Detect fish catch - if (actor->id == ACTOR_FISHING && fs->GetPondFishShuffled()) { - Fishing* fish = static_cast(refActor); - - // State 6 -> Fish caught and hoisted - FishIdentity pending = fs->GetPendingFish(); - if (fish->fishState == 6 && !Rando::Fishsanity::IsFish(&pending)) { - pending = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, fish->fishsanityParams); - if (!Flags_GetRandomizerInf(pending.randomizerInf)) { - fs->SetPendingFish(&pending); - // Remove uncaught effect - if (actor->shape.shadowDraw != NULL) { - actor->shape.shadowDraw = NULL; - } - } - } - } - - if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - if (Rando::Fishsanity::IsFish(&fish) && Flags_GetRandomizerInf(fish.randomizerInf)) { - // Remove uncaught effect - if (actor->shape.shadowDraw != NULL) { - actor->shape.shadowDraw = NULL; - } - } - } - - // Reset fish group counter when the group gets culled - if (actor->id == ACTOR_OBJ_MURE && gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && fishGroupCounter > 0 && - !(actor->flags & ACTOR_FLAG_UPDATE_WHILE_CULLED) && fs->GetOverworldFishShuffled()) { - fishGroupCounter = 0; - } - }); - - GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - if (!IS_RANDO || sceneNum != SCENE_ZORAS_DOMAIN) - return; - fishGroupCounter = 0; - }); -} - void RegisterInfiniteUpgrades() { GameInteractor::Instance->RegisterGameHook([]() { if (!IS_RANDO) { @@ -1819,7 +1668,6 @@ void InitMods() { RegisterToTMedallions(); RegisterNoSwim(); RegisterNoWallet(); - RegisterFishsanity(); RegisterInfiniteUpgrades(); RegisterRandomizerCompasses(); NameTag_RegisterHooks(); diff --git a/soh/soh/Enhancements/presets.cpp b/soh/soh/Enhancements/presets.cpp index 57bfd689cad..0a2582c4afa 100644 --- a/soh/soh/Enhancements/presets.cpp +++ b/soh/soh/Enhancements/presets.cpp @@ -42,7 +42,10 @@ void applyPreset(std::vector entries) { void DrawPresetSelector(PresetType presetTypeId) { const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId); const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId); - const uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); + uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); + if(selectedPresetId >= presetTypeDef.presets.size()){ + selectedPresetId = 0; + } const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId); std::string comboboxTooltip = ""; for ( auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter ) { diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 39cd167c22b..53f41daad6f 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -34,6 +34,7 @@ enum RandomizerPreset { RANDOMIZER_PRESET_SPOCK_RACE_NO_LOGIC, RANDOMIZER_PRESET_S6, RANDOMIZER_PRESET_HELL_MODE, + RANDOMIZER_PRESET_BENCHMARK, }; typedef struct PresetEntry { @@ -1120,7 +1121,8 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_NOTHING), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_FOUR_ITEMS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_SHOPSANITY_PRICE_TYCOON), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), @@ -1147,6 +1149,122 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 2), }; +const std::vector BenchmarkPresetEntries = { + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED_DEKU), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_SONGONLY), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_CLOSED), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RewardCount"), 5), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_GREG_REWARD), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrialCount"), 6), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_INTERIOR_ENTRANCE_SHUFFLE_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DecoupleEntrances"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BombchusInLogic"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), + //RANDOTODO add refactored price/scrub/merchant settings + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), RO_BOSS_SOULS_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_BOTH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_MEDALLIONS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), 6), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GossipStoneHints"), RO_GOSSIP_STONES_NEED_NOTHING), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HintClarity"), RO_HINT_CLARITY_CLEAR), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HintDistribution"), RO_HINT_DIST_STRONG), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AltarHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanondorfHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SheikLAHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SariaHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FrogsHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("OoTHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BiggoronHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoesHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ChickensHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MalonHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HBAHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("WarpSongText"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("10GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MaskShopHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), RO_INF_UPGRADES_PROGRESSIVE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkeletonKey"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ItemPool"), RO_ITEM_POOL_BALANCED), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IceTraps"), RO_ICE_TRAPS_NORMAL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), RO_STARTING_OCARINA_FAIRY), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingDekuShield"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMasterSword"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingEponasSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSariasSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSunsSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), 0), + PRESET_ENTRY_S32("gRandomizeStartingHearts", 2), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), RO_GENERIC_ON), +}; + typedef struct PresetDefinition { const char* label; const char* description; @@ -1220,5 +1338,10 @@ const std::map presetTypes = { "All settings maxed but still using glitchless logic. Expect pain.", hellModePresetEntries } }, + { RANDOMIZER_PRESET_BENCHMARK, { + "Benchmark", + "Used for benchmarking the logic.", + BenchmarkPresetEntries + } }, } } } }; diff --git a/soh/soh/Enhancements/randomizer/3drando/category.hpp b/soh/soh/Enhancements/randomizer/3drando/category.hpp index 22522789cfd..fc230b43538 100644 --- a/soh/soh/Enhancements/randomizer/3drando/category.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/category.hpp @@ -1,26 +1,5 @@ #pragma once -enum class Category { - cNull, - cChestMinigame, - cDekuScrub, - cDekuScrubUpgrades, - cSkulltula, - cSong, - cSongDungeonReward, - cCow, - cFish, - cShop, - cMerchant, - cVanillaSmallKey, - cVanillaGFSmallKey, - cVanillaBossKey, - cVanillaMap, - cVanillaCompass, - cAdultTrade, - cBeehive, -}; - enum class OptionCategory { Setting, Toggle, diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 835055ee4a5..1a7e2cad812 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -14,6 +14,7 @@ #include "pool_functions.hpp" //#include "debug.hpp" #include "soh/Enhancements/randomizer/static_data.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include @@ -22,6 +23,57 @@ using namespace CustomMessages; using namespace Rando; + +//RANDOTODO merge into Logic once Logic is a class passed to logic funtions +struct GetAccessableLocationsStruct { + std::vector accessibleLocations; + std::vector regionPool; + //Variables for playthrough + int gsCount; + int maxGsCount; + std::vector buyIgnores; + + //Variables for search + std::vector newItemLocations; + bool updatedEvents; + bool ageTimePropogated; + bool firstIteration; + + //Variables For Validating Entrences + bool haveTimeAccess; + bool foundTempleOfTime; + bool validatedStartingRegion; + bool sphereZeroComplete; + + std::vector itemSphere; + std::list entranceSphere; + + GetAccessableLocationsStruct(int _maxGsCount){ + regionPool = {RR_ROOT}; + gsCount = 0; + maxGsCount = _maxGsCount; + updatedEvents = false; + ageTimePropogated = false; + firstIteration = true; + haveTimeAccess = false; + foundTempleOfTime = false; + validatedStartingRegion = false; + sphereZeroComplete = false; + } + + void InitLoop(){ + firstIteration = false; + ageTimePropogated = false; + updatedEvents = false; + for (Rando::ItemLocation* location : newItemLocations) { + location->ApplyPlacedItemEffect(); + } + newItemLocations.clear(); + itemSphere.clear(); + entranceSphere.clear(); + } +}; + static bool placementFailure = false; static void RemoveStartingItemsFromPool() { @@ -47,14 +99,15 @@ static void RemoveStartingItemsFromPool() { } } -//This function will propogate Time of Day access through the entrance -static bool UpdateToDAccess(Entrance* entrance, SearchMode mode) { +//This function will propagate Time of Day access through the entrance +static bool UpdateToDAccess(Entrance* entrance, bool propagateTimeTravel) { + StartPerformanceTimer(PT_TOD_ACCESS); bool ageTimePropogated = false; - //propogate childDay, childNight, adultDay, and adultNight separately - Area* parent = entrance->GetParentRegion(); - Area* connection = entrance->GetConnectedRegion(); + //propagate childDay, childNight, adultDay, and adultNight separately + Region* parent = entrance->GetParentRegion(); + Region* connection = entrance->GetConnectedRegion(); if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { connection->childDay = true; @@ -74,67 +127,97 @@ static bool UpdateToDAccess(Entrance* entrance, SearchMode mode) { } //special check for temple of time - bool propogateTimeTravel = mode != SearchMode::TimePassAccess && mode != SearchMode::TempleOfTimeAccess; - if (!AreaTable(RR_ROOT)->Adult() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child() && propogateTimeTravel) { - AreaTable(RR_ROOT)->adultDay = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childDay; - AreaTable(RR_ROOT)->adultNight = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childNight; - } else if (!AreaTable(RR_ROOT)->Child() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult() && propogateTimeTravel){ - AreaTable(RR_ROOT)->childDay = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultDay; - AreaTable(RR_ROOT)->childNight = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; + if (propagateTimeTravel && !RegionTable(RR_ROOT)->Adult() && RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child()) { //RANDOTODO: sphere weirdness, other age locations not propagated in this sphere + RegionTable(RR_ROOT)->adultDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childDay; + RegionTable(RR_ROOT)->adultNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childNight; + } else if (propagateTimeTravel && !RegionTable(RR_ROOT)->Child() && RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult()){ + RegionTable(RR_ROOT)->childDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultDay; + RegionTable(RR_ROOT)->childNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; } + StopPerformanceTimer(PT_TOD_ACCESS); return ageTimePropogated; } -// Various checks that need to pass for the world to be validated as completable -static void ValidateWorldChecks(SearchMode& mode, bool checkPoeCollectorAccess, bool checkOtherEntranceAccess, std::vector& areaPool) { +// Check if key locations in the overworld are accessable +static void ValidateOtherEntrance(GetAccessableLocationsStruct& gals) { auto ctx = Rando::Context::GetInstance(); // Condition for validating Temple of Time Access - if (mode == SearchMode::TempleOfTimeAccess && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && AreaTable(RR_TEMPLE_OF_TIME)->Adult()) || (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && AreaTable(RR_TEMPLE_OF_TIME)->Child()) || !checkOtherEntranceAccess)) { - mode = SearchMode::ValidStartingRegion; + if (!gals.foundTempleOfTime && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) || + (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) { + gals.foundTempleOfTime = true; } // Condition for validating a valid starting region - if (mode == SearchMode::ValidStartingRegion) { - bool childAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD || AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); - bool adultAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT || AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); - - Area* kokiri = AreaTable(RR_KOKIRI_FOREST); - Area* kakariko = AreaTable(RR_KAKARIKO_VILLAGE); - - if ((childAccess && (kokiri->Child() || kakariko->Child())) || - (adultAccess && (kokiri->Adult() || kakariko->Adult())) || - !checkOtherEntranceAccess) { - mode = SearchMode::PoeCollectorAccess; - ApplyStartingInventory(); - logic->NoBottles = true; + if (!gals.validatedStartingRegion) { + bool childAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); + bool adultAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); + + Region* kokiri = RegionTable(RR_KOKIRI_FOREST); + Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE); + + if ((childAccess && (kokiri->Child() || kakariko->Child())) ||// RANDOTODO when proper ammo logic is done, this could probably be made optional + (adultAccess && (kokiri->Adult() || kakariko->Adult()))) { + gals.validatedStartingRegion = true; + ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start } } - // Condition for validating Poe Collector Access - if (mode == SearchMode::PoeCollectorAccess && (AreaTable(RR_MARKET_GUARD_HOUSE)->Adult() || !checkPoeCollectorAccess)) { +} + +// Apply all items that are necessary for checking all location access +static void ApplyAllAdvancmentItems(){ + std::vector itemsToPlace = + FilterFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); + for (RandomizerGet unplacedItem : itemsToPlace) { + Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); + } +} + +// Check if everything in an entrence rando seed that needs to be avalible without items, is, +// and if so allow obtaining items in logic +static void ValidateSphereZero(GetAccessableLocationsStruct& gals){ + auto ctx = Rando::Context::GetInstance(); + // Condition for verifying everything required for sphere 0, expanding search to all locations + if (logic->CanEmptyBigPoes && gals.validatedStartingRegion && gals.foundTempleOfTime && gals.haveTimeAccess) { // Apply all items that are necessary for checking all location access - std::vector itemsToPlace = - FilterFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); - for (RandomizerGet unplacedItem : itemsToPlace) { - Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); - } + ApplyAllAdvancmentItems(); // Reset access as the non-starting age if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { - for (RandomizerRegion areaKey : areaPool) { - AreaTable(areaKey)->adultDay = false; - AreaTable(areaKey)->adultNight = false; + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->adultDay = false; + RegionTable(regionKey)->adultNight = false; } } else { - for (RandomizerRegion areaKey : areaPool) { - AreaTable(areaKey)->childDay = false; - AreaTable(areaKey)->childNight = false; + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->childDay = false; + RegionTable(regionKey)->childNight = false; } } - mode = SearchMode::AllLocationsReachable; - } else { - logic->NoBottles = false; + gals.sphereZeroComplete = true; + } +} + +//This function handles each possible exit +void ProcessExit(Entrance& exit, GetAccessableLocationsStruct& gals, bool propagateTimeTravel = true, bool checkPoeCollectorAccess = false, bool checkOtherEntranceAccess = false){ + //Update Time of Day Access for the exit + if (UpdateToDAccess(&exit, propagateTimeTravel)) { + gals.ageTimePropogated = true; + if (checkOtherEntranceAccess){ + ValidateOtherEntrance(gals); + } + if (!gals.sphereZeroComplete){ + ValidateSphereZero(gals); + } + } + + //If the exit is accessible and hasn't been added yet, add it to the pool + Region* exitRegion = exit.GetConnectedRegion(); + if (!exitRegion->addedToPool && exit.ConditionsMet()) { + exitRegion->addedToPool = true; + gals.regionPool.push_back(exit.GetConnectedRegionKey()); } } + //Get the max number of tokens that can possibly be useful static int GetMaxGSCount() { auto ctx = Rando::Context::GetInstance(); @@ -186,9 +269,9 @@ std::string GetShopItemBaseName(std::string itemName) { return baseName; } -std::vector GetEmptyLocations(std::vector allowedLocations) { +std::vector GetEmptyLocations(std::vector targetLocations) { auto ctx = Rando::Context::GetInstance(); - return FilterFromPool(allowedLocations, [ctx](const auto loc) { + return FilterFromPool(targetLocations, [ctx](const auto loc) { return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_NONE; }); } @@ -211,46 +294,233 @@ bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, Randomiz ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); //Write in empty item ctx->playthroughBeatable = false; logic->Reset(); - GetAccessibleLocations(ctx->allLocations, SearchMode::CheckBeatable, ignore); //Check if game is still beatable + CheckBeatable(ignore); if (replaceItem){ ctx->GetItemLocation(excludedCheck)->SetPlacedItem(copy); //Immediately put item back } return ctx->playthroughBeatable; } -//This function will return a vector of ItemLocations that are accessible with -//where items have been placed so far within the world. The allowedLocations argument -//specifies the pool of locations that we're trying to search for an accessible location in -std::vector GetAccessibleLocations(const std::vector& allowedLocations, SearchMode mode /* = SearchMode::ReachabilitySearch*/, RandomizerGet ignore /* = RG_NONE*/, bool checkPoeCollectorAccess /*= false*/, bool checkOtherEntranceAccess /*= false*/) { - auto ctx = Rando::Context::GetInstance(); - std::vector accessibleLocations; - // Reset all access to begin a new search - if (mode < SearchMode::ValidateWorld) { - ApplyStartingInventory(); +// Reset non-Logic-class logic, and optionally apply the initial inventory +void ResetLogic(std::shared_ptr& ctx, bool applyInventory = false){ + if (applyInventory){ + ApplyStartingInventory(); } - Areas::AccessReset(); + Regions::AccessReset(); ctx->LocationReset(); - std::vector areaPool = {RR_ROOT}; - - if (mode == SearchMode::ValidateWorld) { - mode = SearchMode::TimePassAccess; - AreaTable(RR_ROOT)->childNight = true; - AreaTable(RR_ROOT)->adultNight = true; - AreaTable(RR_ROOT)->childDay = true; - AreaTable(RR_ROOT)->adultDay = true; - ctx->allLocationsReachable = false; +} + +//Generate the playthrough, so we want to add advancement items, unless we know to ignore them +void AddToPlaythrough(LocationAccess& locPair, GetAccessableLocationsStruct& gals){ + auto ctx = Rando::Context::GetInstance(); + RandomizerCheck loc = locPair.GetLocation(); + Rando::ItemLocation* location = ctx->GetItemLocation(loc); + RandomizerGet locItem = location->GetPlacedRandomizerGet(); + //Item is an advancement item, figure out if it should be added to this sphere + if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { + ItemType type = location->GetPlacedItem().GetItemType(); + + //Decide whether to exclude this location + //This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough + //Want to exclude: + //1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for token bridge) + //2) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once) + bool exclude = true; + //Exclude tokens after the last possibly useful one + if (type == ITEMTYPE_TOKEN && gals.gsCount < gals.maxGsCount) { + gals.gsCount++; + exclude = false; + } + //Handle buy items + //If ammo drops are off, don't do this step, since buyable ammo becomes logically important + // TODO: Reimplement Ammo Drops setting + else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ type == ITEMTYPE_SHOP) { + //Only check each buy item once + auto buyItem = location->GetPlacedItem().GetLogicVal(); + //Buy item not in list to ignore, add it to list and write to playthrough + if (std::find(gals.buyIgnores.begin(), gals.buyIgnores.end(), buyItem) == gals.buyIgnores.end()) { + exclude = false; + gals.buyIgnores.push_back(buyItem); + } + } + //Add all other advancement items + else if (type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) { + exclude = false; + } + //Has not been excluded, add to playthrough + if (!exclude) { + gals.itemSphere.push_back(loc); + } } + //Triforce has been found, seed is beatable, nothing else in this or future spheres matters + else if (location->GetPlacedRandomizerGet() == RG_TRIFORCE) { + gals.itemSphere.clear(); + gals.itemSphere.push_back(loc); + ctx->playthroughBeatable = true; + } +} - //Variables for playthrough - int gsCount = 0; - const int maxGsCount = mode == SearchMode::GeneratePlaythrough ? GetMaxGSCount() : 0; //If generating playthrough want the max that's possibly useful, else doesn't matter - std::vector buyIgnores; +// Adds the contents of a location to the current progression and optionally playthrough +bool AddCheckToLogic(LocationAccess& locPair, GetAccessableLocationsStruct& gals, RandomizerGet ignore, bool stopOnBeatable, bool addToPlaythrough=false){ + auto ctx = Rando::Context::GetInstance(); + StartPerformanceTimer(PT_LOCATION_LOGIC); + RandomizerCheck loc = locPair.GetLocation(); + Rando::ItemLocation* location = ctx->GetItemLocation(loc); + RandomizerGet locItem = location->GetPlacedRandomizerGet(); - //Variables for search - std::vector newItemLocations; - bool updatedEvents = false; - bool ageTimePropogated = false; - bool firstIteration = true; + if (!location->IsAddedToPool() && locPair.ConditionsMet()) { + location->AddToPool(); + + if (locItem == RG_NONE) { + gals.accessibleLocations.push_back(loc); //Empty location, consider for placement + } else { + //If ignore has a value, we want to check if the item location should be considered or not + //This is necessary due to the below preprocessing for playthrough generation + if (ignore != RG_NONE) { + ItemType type = location->GetPlacedItem().GetItemType(); + //If we want to ignore tokens, only add if not a token + if (ignore == RG_GOLD_SKULLTULA_TOKEN && type != ITEMTYPE_TOKEN) { + gals.newItemLocations.push_back(location); + } + //If we want to ignore bombchus, only add if bombchu is not in the name + else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { + gals.newItemLocations.push_back(location); + } + //We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a shared GetLogicVal + else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) { + if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVal() != location->GetPlacedItem().GetLogicVal()) || type != ITEMTYPE_SHOP) { + gals.newItemLocations.push_back(location); + } + } + } + //If it doesn't, we can just add the location + else { + gals.newItemLocations.push_back(location); //Add item to cache to be considered in logic next iteration + } + } + if (addToPlaythrough){ + AddToPlaythrough(locPair, gals); + } + //All we care about is if the game is beatable, used to pare down playthrough + if (location->GetPlacedRandomizerGet() == RG_TRIFORCE && stopOnBeatable) { + StopPerformanceTimer(PT_LOCATION_LOGIC); + return true; //Return early for efficiency + } + } + StopPerformanceTimer(PT_LOCATION_LOGIC); + return false; +} + +// Return any of the targetLocations that are accessible in logic +std::vector ReachabilitySearch(const std::vector& targetLocations, RandomizerGet ignore /* = RG_NONE*/) { + auto ctx = Rando::Context::GetInstance(); + GetAccessableLocationsStruct gals(0); + ResetLogic(ctx, true); + while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + Region* region = RegionTable(gals.regionPool[i]); + + if (region->UpdateEvents()){ + gals.updatedEvents = true; + } + for (auto& exit : region->exits) { + ProcessExit(exit, gals); + } + for (size_t k = 0; k < region->locations.size(); k++) { + LocationAccess& locPair = region->locations[k]; + AddCheckToLogic(locPair, gals, ignore, false); + } + } + } + erase_if(gals.accessibleLocations, [&targetLocations, ctx](RandomizerCheck loc){ + for (RandomizerCheck allowedLocation : targetLocations) { + if (loc == allowedLocation || ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() != RG_NONE) { + return false; + } + } + return true; + }); + return gals.accessibleLocations; +} + +// Create the playthrough for the seed +void GeneratePlaythrough() { + auto ctx = Rando::Context::GetInstance(); + ctx->playthroughBeatable = false; + logic->Reset(); + GetAccessableLocationsStruct gals(GetMaxGSCount()); + ResetLogic(ctx, true); + while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + Region* region = RegionTable(gals.regionPool[i]); + + if (region->UpdateEvents()){ + gals.updatedEvents = true; + } + for (auto& exit : region->exits) { + ProcessExit(exit, gals); + // Add shuffled entrances to the entrance playthrough + // Include bluewarps when unshuffled but dungeon or boss shuffle is on + if((exit.IsShuffled() || (exit.GetType() == Rando::EntranceType::BlueWarp && + (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES)))) && + !exit.IsAddedToPool() && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { + gals.entranceSphere.push_back(&exit); + exit.AddToPool(); + // Don't list a two-way coupled entrance from both directions + if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !exit.IsDecoupled()) { + exit.GetReplacement()->GetReverse()->AddToPool(); + } + } + } + for (size_t k = 0; k < region->locations.size(); k++) { + LocationAccess& locPair = region->locations[k]; + AddCheckToLogic(locPair, gals, RG_NONE, false, true); + } + } + if (gals.itemSphere.size() > 0) { + ctx->playthroughLocations.push_back(gals.itemSphere); + } + if (gals.entranceSphere.size() > 0 && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { + ctx->GetEntranceShuffler()->playthroughEntrances.push_back(gals.entranceSphere); + } + } +} + +// return if the seed is currently beatable or not +bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) { + auto ctx = Rando::Context::GetInstance(); + GetAccessableLocationsStruct gals(0); + ResetLogic(ctx, true); + while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + Region* region = RegionTable(gals.regionPool[i]); + + if (region->UpdateEvents()){ + gals.updatedEvents = true; + } + for (auto& exit : region->exits) { + ProcessExit(exit, gals); + } + for (size_t k = 0; k < region->locations.size(); k++) { + LocationAccess& locPair = region->locations[k]; + if(AddCheckToLogic(locPair, gals, ignore, true)){ + ctx->playthroughBeatable = true; + return true; + } + } + } + } + return false; +} + +// Check if the currently randomised set of entrences is a valid game map. +void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess) { + auto ctx = Rando::Context::GetInstance(); + GetAccessableLocationsStruct gals(0); + ResetLogic(ctx, !checkOtherEntranceAccess); //Variables for Time Pass access bool timePassChildDay = false; @@ -258,192 +528,82 @@ std::vector GetAccessibleLocations(const std::vector 0 || updatedEvents || ageTimePropogated || firstIteration) { - firstIteration = false; - ageTimePropogated = false; - updatedEvents = false; - - for (Rando::ItemLocation* location : newItemLocations) { - location->ApplyPlacedItemEffect(); + ctx->allLocationsReachable = false; + if (checkPoeCollectorAccess){ + logic->CanEmptyBigPoes = false; + } + if (!checkOtherEntranceAccess){ + gals.foundTempleOfTime = true; + gals.validatedStartingRegion = true; + gals.haveTimeAccess = true; + gals.sphereZeroComplete = true; + ApplyAllAdvancmentItems(); + //if we assume valid sphere zero, we only want starting age access + if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->childDay = true; + } + } else { + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultDay = true; + } } - newItemLocations.clear(); - - std::vector itemSphere; - std::list entranceSphere; + } else { + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->adultDay = true; + } - for (size_t i = 0; i < areaPool.size(); i++) { - Area* area = AreaTable(areaPool[i]); + while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + Region* region = RegionTable(gals.regionPool[i]); - if (area->UpdateEvents(mode)){ - updatedEvents = true; + if (region->UpdateEvents(gals.haveTimeAccess)){ + gals.updatedEvents = true; } - - // If we're checking for TimePass access do that for each area as it's being updated. - // TimePass Access is satisfied when every AgeTime can reach an area with TimePass + // If we're checking for TimePass access do that for each region as it's being updated. + // TimePass Access is satisfied when every AgeTime can reach a region with TimePass // without the aid of TimePass. During this mode, TimePass won't update ToD access - // in any area. - if (mode == SearchMode::TimePassAccess) { - if (area->timePass) { - if (area->childDay) { + // in any region. + if (!gals.haveTimeAccess) { + if (region->timePass) { + if (region->childDay) { timePassChildDay = true; } - if (area->childNight) { + if (region->childNight) { timePassChildNight = true; } - if (area->adultDay) { + if (region->adultDay) { timePassAdultDay = true; } - if (area->adultNight) { + if (region->adultNight) { timePassAdultNight = true; } } // Condition for validating that all startring AgeTimes have timepass access // Once satisifed, change the mode to begin checking for Temple of Time Access - if ((timePassChildDay && timePassChildNight && timePassAdultDay && timePassAdultNight) || !checkOtherEntranceAccess) { - mode = SearchMode::TempleOfTimeAccess; - } - } - - //for each exit in this area - for (auto& exit : area->exits) { - - //Update Time of Day Access for the exit - if (UpdateToDAccess(&exit, mode)) { - ageTimePropogated = true; - ValidateWorldChecks(mode, checkPoeCollectorAccess, checkOtherEntranceAccess, areaPool); - } - - //If the exit is accessible and hasn't been added yet, add it to the pool - Area* exitArea = exit.GetConnectedRegion(); - if (!exitArea->addedToPool && exit.ConditionsMet()) { - exitArea->addedToPool = true; - areaPool.push_back(exit.GetConnectedRegionKey()); - } - - // Add shuffled entrances to the entrance playthrough - // Include bluewarps when unshuffled but dungeon or boss shuffle is on - if (mode == SearchMode::GeneratePlaythrough && - (exit.IsShuffled() || - (exit.GetType() == Rando::EntranceType::BlueWarp && - (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES)))) && - !exit.IsAddedToPool() && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { - entranceSphere.push_back(&exit); - exit.AddToPool(); - // Don't list a two-way coupled entrance from both directions - if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !exit.IsDecoupled()) { - exit.GetReplacement()->GetReverse()->AddToPool(); - } + if (timePassChildDay && timePassChildNight && timePassAdultDay && timePassAdultNight) { + gals.haveTimeAccess = true; } } - //for each ItemLocation in this area - if (mode < SearchMode::ValidateWorld) { - for (size_t k = 0; k < area->locations.size(); k++) { - LocationAccess& locPair = area->locations[k]; - RandomizerCheck loc = locPair.GetLocation(); - Rando::ItemLocation* location = ctx->GetItemLocation(loc); - RandomizerGet locItem = location->GetPlacedRandomizerGet(); - - if (!location->IsAddedToPool() && locPair.ConditionsMet()) { - - location->AddToPool(); - - if (locItem == RG_NONE) { - accessibleLocations.push_back(loc); //Empty location, consider for placement - } else { - //If ignore has a value, we want to check if the item location should be considered or not - //This is necessary due to the below preprocessing for playthrough generation - if (ignore != RG_NONE) { - ItemType type = location->GetPlacedItem().GetItemType(); - //If we want to ignore tokens, only add if not a token - if (ignore == RG_GOLD_SKULLTULA_TOKEN && type != ITEMTYPE_TOKEN) { - newItemLocations.push_back(location); - } - //If we want to ignore bombchus, only add if bombchu is not in the name - else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { - newItemLocations.push_back(location); - } - //We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a shared GetLogicVal - else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) { - if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVal() != location->GetPlacedItem().GetLogicVal()) || type != ITEMTYPE_SHOP) { - newItemLocations.push_back(location); - } - } - } - //If it doesn't, we can just add the location - else { - newItemLocations.push_back(location); //Add item to cache to be considered in logic next iteration - } - } - - //Playthrough stuff - //Generate the playthrough, so we want to add advancement items, unless we know to ignore them - if (mode == SearchMode::GeneratePlaythrough) { - //Item is an advancement item, figure out if it should be added to this sphere - if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { - ItemType type = location->GetPlacedItem().GetItemType(); - - //Decide whether to exclude this location - //This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough - //Want to exclude: - //1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for token bridge) - //2) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once) - bool exclude = true; - //Exclude tokens after the last possibly useful one - if (type == ITEMTYPE_TOKEN && gsCount < maxGsCount) { - gsCount++; - exclude = false; - } - - //Handle buy items - //If ammo drops are off, don't do this step, since buyable ammo becomes logically important - // TODO: Reimplement Ammo Drops setting - else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ type == ITEMTYPE_SHOP) { - //Only check each buy item once - auto buyItem = location->GetPlacedItem().GetLogicVal(); - //Buy item not in list to ignore, add it to list and write to playthrough - if (std::find(buyIgnores.begin(), buyIgnores.end(), buyItem) == buyIgnores.end()) { - exclude = false; - buyIgnores.push_back(buyItem); - } - } - //Add all other advancement items - else if (type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) { - exclude = false; - } - //Has not been excluded, add to playthrough - if (!exclude) { - itemSphere.push_back(loc); - } - } - //Triforce has been found, seed is beatable, nothing else in this or future spheres matters - else if (location->GetPlacedRandomizerGet() == RG_TRIFORCE) { - itemSphere.clear(); - itemSphere.push_back(loc); - ctx->playthroughBeatable = true; - } - } - //All we care about is if the game is beatable, used to pare down playthrough - else if (location->GetPlacedRandomizerGet() == RG_TRIFORCE && mode == SearchMode::CheckBeatable) { - ctx->playthroughBeatable = true; - return {}; //Return early for efficiency - } - } + //for each exit in this region + for (auto& exit : region->exits) { + ProcessExit(exit, gals, gals.haveTimeAccess && gals.foundTempleOfTime, checkPoeCollectorAccess, checkOtherEntranceAccess); + } + if (gals.sphereZeroComplete) { + for (size_t k = 0; k < region->locations.size(); k++) { + LocationAccess& locPair = region->locations[k]; + AddCheckToLogic(locPair, gals, RG_NONE, false); } } } - - if (mode == SearchMode::GeneratePlaythrough && itemSphere.size() > 0) { - ctx->playthroughLocations.push_back(itemSphere); - } - if (mode == SearchMode::GeneratePlaythrough && entranceSphere.size() > 0 && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { - ctx->GetEntranceShuffler()->playthroughEntrances.push_back(entranceSphere); - } } - - //Check to see if all locations were reached - if (mode == SearchMode::AllLocationsReachable) { + if (gals.sphereZeroComplete) { ctx->allLocationsReachable = true; for (const RandomizerCheck loc : ctx->allLocations) { if (!ctx->GetItemLocation(loc)->IsAddedToPool()) { @@ -457,28 +617,10 @@ std::vector GetAccessibleLocations(const std::vectorGetItemLocation(loc)->GetPlacedRandomizerGet() != RG_NONE) { - return false; - } - } - return true; - }); - return accessibleLocations; } -static void GeneratePlaythrough() { - auto ctx = Rando::Context::GetInstance(); - ctx->playthroughBeatable = false; - logic->Reset(); - GetAccessibleLocations(ctx->allLocations, SearchMode::GeneratePlaythrough); -} - -RandomizerArea LookForExternalArea(const Area* const currentRegion, std::vector &alreadyChecked){ +RandomizerArea LookForExternalArea(const Region* const currentRegion, std::vector &alreadyChecked){ for (const auto& entrance : currentRegion->entrances) { RandomizerArea otherArea = entrance->GetParentRegion()->GetArea(); const bool isAreaUnchecked = std::find(alreadyChecked.begin(), alreadyChecked.end(), entrance->GetParentRegionKey()) == alreadyChecked.end(); @@ -489,7 +631,7 @@ RandomizerArea LookForExternalArea(const Area* const currentRegion, std::vector< if(passdown != RA_NONE){ return passdown; } - } else if (otherArea != RA_LINKS_POCKET){ //if it's links pocket, do not propogate this, Link's Pocket is not a real Area + } else if (otherArea != RA_LINKS_POCKET){ //if it's links pocket, do not propagate this, Link's Pocket is not a real Area return otherArea; } } @@ -500,7 +642,7 @@ void SetAreas(){ auto ctx = Rando::Context::GetInstance(); //RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here, the use those areas to not need to recursivly find ItemLocation areas for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) { - Area region = areaTable[regionType]; + Region region = areaTable[regionType]; RandomizerArea area = region.GetArea(); if (area == RA_NONE) { std::vector alreadyChecked = {static_cast(regionType)}; @@ -576,7 +718,7 @@ static void CalculateWotH() { } ctx->playthroughBeatable = true; logic->Reset(); - GetAccessibleLocations(ctx->allLocations); + ReachabilitySearch(ctx->allLocations); } //Calculate barren locations and assign Barren Candidacy to all locations inside those areas @@ -687,7 +829,7 @@ static void AssumedFill(const std::vector& items, const std::vect } // get all accessible locations that are allowed - const std::vector accessibleLocations = GetAccessibleLocations(allowedLocations); + const std::vector accessibleLocations = ReachabilitySearch(allowedLocations); // retry if there are no more locations to place items if (accessibleLocations.empty()) { @@ -697,7 +839,7 @@ static void AssumedFill(const std::vector& items, const std::vect SPDLOG_DEBUG(". TRYING AGAIN...\n"); #ifdef ENABLE_DEBUG - Areas::DumpWorldGraph(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); + Regions::DumpWorldGraph(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); PlacementLog_Write(); #endif @@ -729,7 +871,7 @@ static void AssumedFill(const std::vector& items, const std::vect if (!ctx->GetOption(RSK_ALL_LOCATIONS_REACHABLE)) { ctx->playthroughBeatable = false; logic->Reset(); - GetAccessibleLocations(ctx->allLocations, SearchMode::CheckBeatable); + CheckBeatable(); if (ctx->playthroughBeatable) { SPDLOG_DEBUG("Game beatable, now placing items randomly. " + std::to_string(itemsToPlace.size()) + " major items remaining.\n\n"); @@ -835,12 +977,14 @@ static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { }); //filter out locations that may be required to have songs placed at them - dungeonLocations = FilterFromPool(dungeonLocations, [ctx](const auto loc){ + dungeonLocations = FilterFromPool(dungeonLocations, [ctx](const auto loc) { if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { - return !(Rando::StaticData::GetLocation(loc)->IsCategory(Category::cSong)); + return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION); } - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { - return !(Rando::StaticData::GetLocation(loc)->IsCategory(Category::cSongDungeonReward)); + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { + return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || + loc == RC_SHEIK_IN_ICE_CAVERN || + loc == RC_SONG_FROM_IMPA); } return true; }); @@ -879,8 +1023,8 @@ static void RandomizeDungeonItems() { auto ctx = Rando::Context::GetInstance(); //Get Any Dungeon and Overworld group locations - std::vector anyDungeonLocations = FilterFromPool(ctx->allLocations, [](const auto loc){return Rando::StaticData::GetLocation(loc)->IsDungeon();}); - //overworldLocations defined in item_location.cpp + std::vector anyDungeonLocations = Rando::StaticData::GetDungeonLocations(); + //Rando::StaticData::GetOverworldLocations() defined in item_location.cpp //Create Any Dungeon and Overworld item pools std::vector anyDungeonItems; @@ -932,7 +1076,7 @@ static void RandomizeDungeonItems() { //Randomize Any Dungeon and Overworld pools AssumedFill(anyDungeonItems, anyDungeonLocations, true); - AssumedFill(overworldItems, Rando::StaticData::overworldLocations, true); + AssumedFill(overworldItems, Rando::StaticData::GetOverworldLocations(), true); //Randomize maps and compasses after since they're not advancement items for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { @@ -941,7 +1085,7 @@ static void RandomizeDungeonItems() { AssumedFill(mapAndCompassItems, anyDungeonLocations, true); } else if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); - AssumedFill(mapAndCompassItems, Rando::StaticData::overworldLocations, true); + AssumedFill(mapAndCompassItems, Rando::StaticData::GetOverworldLocations(), true); } } } @@ -967,7 +1111,7 @@ static void RandomizeLinksPocket() { void VanillaFill() { auto ctx = Rando::Context::GetInstance(); //Perform minimum needed initialization - AreaTable_Init(); + RegionTable_Init(); ctx->GenerateLocationPool(); GenerateItemPool(); GenerateStartingInventory(); @@ -1003,7 +1147,7 @@ int Fill() { //showItemProgress = false; ctx->playthroughLocations.clear(); ctx->GetEntranceShuffler()->playthroughEntrances.clear(); - AreaTable_Init(); //Reset the world graph to intialize the proper locations + RegionTable_Init(); //Reset the world graph to intialize the proper locations ctx->ItemReset(); //Reset shops incase of shopsanity random ctx->GenerateLocationPool(); GenerateItemPool(); @@ -1013,7 +1157,8 @@ int Fill() { //Temporarily add shop items to the ItemPool so that entrance randomization //can validate the world using deku/hylian shields - AddElementsToPool(ItemPool, GetMinVanillaShopItems(32)); //assume worst case shopsanity 4 + StartPerformanceTimer(PT_ENTRANCE_SHUFFLE); + AddElementsToPool(ItemPool, GetMinVanillaShopItems(8)); //assume worst case shopsanity 7 if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { SPDLOG_INFO("Shuffling Entrances..."); if (ctx->GetEntranceShuffler()->ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) { @@ -1026,37 +1171,47 @@ int Fill() { SetAreas(); //erase temporary shop items FilterAndEraseFromPool(ItemPool, [](const auto item) { return Rando::StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_SHOP; }); + StopPerformanceTimer(PT_ENTRANCE_SHUFFLE); //ctx->showItemProgress = true; //Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access - NonShopItems = {}; + + StartPerformanceTimer(PT_SHOPSANITY); + NonShopItems.clear(); if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { SPDLOG_INFO("Placing Vanilla Shop Items..."); PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location } else { SPDLOG_INFO("Shuffling Shop Items"); int total_replaced = 0; - if (ctx->GetOption(RSK_SHOPSANITY).IsNot(RO_SHOPSANITY_ZERO_ITEMS)) { //Shopsanity 1-4, random - //Initialize NonShopItems - ItemAndPrice init; - init.Name = Text{"No Item", "Sin objeto", "Pas d'objet"}; - init.Price = -1; - init.Repurchaseable = false; - NonShopItems.assign(32, init); - //Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. - const std::array indices = {7, 5, 8, 6}; + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_RANDOM) || ctx->GetOption(RSK_SHOPSANITY_COUNT).IsNot(RO_SHOPSANITY_COUNT_ZERO_ITEMS)) { //Shopsanity 1-7, random + /* + Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. + 8 6 2 4 + 7 5 1 3 + */ + const std::array indices = { 7, 5, 8, 6, 3, 1, 4, 2 }; //Overwrite appropriate number of shop items - for (size_t i = 0; i < Rando::StaticData::shopLocationLists.size(); i++) { - int num_to_replace = GetShopsanityReplaceAmount(); //1-4 shop items will be overwritten, depending on settings + #define LOCATIONS_PER_SHOP 8 + for (size_t i = 0; i < Rando::StaticData::GetShopLocations().size() / LOCATIONS_PER_SHOP; i++) { + int num_to_replace = GetShopsanityReplaceAmount(); //1-7 shop items will be overwritten, depending on settings total_replaced += num_to_replace; for (int j = 0; j < num_to_replace; j++) { int itemindex = indices[j]; int shopsanityPrice = GetRandomShopPrice(); - NonShopItems[TransformShopIndex(i * 8 + itemindex - 1)].Price = - shopsanityPrice; // Set price to be retrieved by the patch and textboxes - ctx->GetItemLocation(Rando::StaticData::shopLocationLists[i][itemindex - 1])->SetCustomPrice(shopsanityPrice); + NonShopItems[Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]].Price = shopsanityPrice; // Set price to be retrieved by the patch and textboxes + ctx->GetItemLocation(Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1])->SetCustomPrice(shopsanityPrice); + } + for (int j = num_to_replace; j < 8; j++) { + ItemAndPrice init; + init.Name = Text { "No Item", "Sin objeto", "Pas d'objet" }; + init.Price = -1; + init.Repurchaseable = false; + int itemindex = indices[j]; + NonShopItems[Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]] = init; // Set price to be retrieved by the patch and textboxes } } + #undef LOCATIONS_PER_SHOP } //Get all locations and items that don't have a shopsanity price attached std::vector shopLocations = {}; @@ -1064,18 +1219,17 @@ int Fill() { //So shopsanity 0 will get all 64 vanilla items, shopsanity 4 will get 32, etc. std::vector shopItems = GetMinVanillaShopItems(total_replaced); - for (size_t i = 0; i < Rando::StaticData::shopLocationLists.size(); i++) { - for (size_t j = 0; j < Rando::StaticData::shopLocationLists[i].size(); j++) { - RandomizerCheck loc = Rando::StaticData::shopLocationLists[i][j]; - if (!(ctx->GetItemLocation(loc)->HasCustomPrice())) { - shopLocations.push_back(loc); - } + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { + if (!(ctx->GetItemLocation(randomizerCheck)->HasCustomPrice())) { + shopLocations.push_back(randomizerCheck); } } //Place the shop items which will still be at shop locations AssumedFill(shopItems, shopLocations); } + StopPerformanceTimer(PT_SHOPSANITY); + StartPerformanceTimer(PT_OWN_DUNGEON); //Place dungeon rewards SPDLOG_INFO("Shuffling and Placing Dungeon Items..."); RandomizeDungeonRewards(); @@ -1084,7 +1238,9 @@ int Fill() { for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { RandomizeOwnDungeon(dungeon); } + StopPerformanceTimer(PT_OWN_DUNGEON); + StartPerformanceTimer(PT_LIMITED_CHECKS); //Then Place songs if song shuffle is set to specific locations if (ctx->GetOption(RSK_SHUFFLE_SONGS).IsNot(RO_SONG_SHUFFLE_ANYWHERE)) { @@ -1096,11 +1252,13 @@ int Fill() { std::vector songLocations; if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { songLocations = FilterFromPool( - ctx->allLocations, [](const auto loc) { return Rando::StaticData::GetLocation(loc)->IsCategory(Category::cSong); }); + ctx->allLocations, [](const auto loc) { return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; }); } else if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { songLocations = FilterFromPool(ctx->allLocations, [](const auto loc) { - return Rando::StaticData::GetLocation(loc)->IsCategory(Category::cSongDungeonReward); + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || + loc == RC_SHEIK_IN_ICE_CAVERN || + loc == RC_SONG_FROM_IMPA; }); } @@ -1113,60 +1271,82 @@ int Fill() { //Then place Link's Pocket Item if it has to be an advancement item RandomizeLinksPocket(); + StopPerformanceTimer(PT_LIMITED_CHECKS); + + + StartPerformanceTimer(PT_ADVANCEMENT_ITEMS); SPDLOG_INFO("Shuffling Advancement Items"); //Then place the rest of the advancement items std::vector remainingAdvancementItems = FilterAndEraseFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); AssumedFill(remainingAdvancementItems, ctx->allLocations, true); + StopPerformanceTimer(PT_ADVANCEMENT_ITEMS); + StartPerformanceTimer(PT_REMAINING_ITEMS); //Fast fill for the rest of the pool SPDLOG_INFO("Shuffling Remaining Items"); std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); FastFill(remainingPool, GetAllEmptyLocations(), false); + StopPerformanceTimer(PT_REMAINING_ITEMS); //Add default prices to scrubs - for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) { - if (Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_GROTTO_FRONT) { - ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(40); - } else if (Rando::StaticData::scrubLocations[i] == RC_HF_DEKU_SCRUB_GROTTO) { - ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10); + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) { + if (randomizerCheck == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || randomizerCheck == RC_LW_DEKU_SCRUB_GROTTO_FRONT) { + ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(40); + } else if (randomizerCheck == RC_HF_DEKU_SCRUB_GROTTO) { + ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(10); } else { - auto loc = Rando::StaticData::GetLocation(Rando::StaticData::scrubLocations[i]); + auto loc = Rando::StaticData::GetLocation(randomizerCheck); auto item = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()); - ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(item.GetPrice()); + ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(item.GetPrice()); } } if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_AFFORDABLE)) { - for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) { - ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10); + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) { + ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(10); } } else if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_RANDOM)) { - for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) { - int randomPrice = GetRandomScrubPrice(); - ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(randomPrice); + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) { + ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(GetRandomScrubPrice()); } } + StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); GeneratePlaythrough(); + StopPerformanceTimer(PT_PLAYTHROUGH_GENERATION); //Successful placement, produced beatable result if(ctx->playthroughBeatable && !placementFailure) { + SPDLOG_INFO("Calculating Playthrough..."); + StartPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); PareDownPlaythrough(); + StopPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); + + StartPerformanceTimer(PT_WOTH); CalculateWotH(); + StopPerformanceTimer(PT_WOTH); + + StartPerformanceTimer(PT_FOOLISH); CalculateBarren(); + StopPerformanceTimer(PT_FOOLISH); SPDLOG_INFO("Calculating Playthrough Done"); + + StartPerformanceTimer(PT_OVERRIDES); ctx->CreateItemOverrides(); ctx->GetEntranceShuffler()->CreateEntranceOverrides(); - + StopPerformanceTimer(PT_OVERRIDES); + + StartPerformanceTimer(PT_HINTS); CreateAllHints(); CreateWarpSongTexts(); + StopPerformanceTimer(PT_HINTS); return 1; } //Unsuccessful placement if(retries < 4) { SPDLOG_DEBUG("Failed to generate a beatable seed. Retrying..."); - Areas::ResetAllLocations(); + Regions::ResetAllLocations(); logic->Reset(); ClearProgress(); } diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.hpp b/soh/soh/Enhancements/randomizer/3drando/fill.hpp index 2dd6c21c898..60feafc16fe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.hpp @@ -5,25 +5,16 @@ #include #include -enum class SearchMode { - ReachabilitySearch, - GeneratePlaythrough, - CheckBeatable, - AllLocationsReachable, - ValidateWorld, - TimePassAccess, - TempleOfTimeAccess, - ValidStartingRegion, - PoeCollectorAccess, -}; - void ClearProgress(); void VanillaFill(); int Fill(); std::vector GetEmptyLocations(std::vector allowedLocations); -std::vector GetAccessibleLocations(const std::vector& allowedLocations, - SearchMode mode = SearchMode::ReachabilitySearch, RandomizerGet ignore = RG_NONE, - bool checkPoeCollectorAccess = false, - bool checkOtherEntranceAccess = false); \ No newline at end of file +std::vector ReachabilitySearch(const std::vector& allowedLocations, RandomizerGet ignore=RG_NONE); + +void GeneratePlaythrough(); + +bool CheckBeatable(RandomizerGet ignore=RG_NONE); + +void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 95f5a114405..9b4eeedf88b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -136,7 +136,7 @@ bool FilterFoolishLocations(RandomizerCheck loc){ bool FilterSongLocations(RandomizerCheck loc){ auto ctx = Rando::Context::GetInstance(); - return Rando::StaticData::GetLocation(loc)->IsCategory(Category::cSong); + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; } bool FilterOverworldLocations(RandomizerCheck loc){ @@ -316,7 +316,7 @@ std::vector>> conditionalAlways }; static std::vector GetEmptyGossipStones() { - auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::gossipStoneLocations); + auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::GetGossipStoneLocations()); return emptyGossipStones; } @@ -328,7 +328,7 @@ static std::vector GetAccessibleGossipStones(const RandomizerCh ctx->GetItemLocation(hintedLocation)->SetPlacedItem(RG_NONE); ctx->GetLogic()->Reset(); - auto accessibleGossipStones = GetAccessibleLocations(Rando::StaticData::gossipStoneLocations); + auto accessibleGossipStones = ReachabilitySearch(Rando::StaticData::GetGossipStoneLocations()); //Give the item back to the location ctx->GetItemLocation(hintedLocation)->SetPlacedItem(originalItem); @@ -342,7 +342,7 @@ bool IsReachableWithout(std::vector locsToCheck, RandomizerChec RandomizerGet originalItem = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); ctx->GetLogic()->Reset(); - const auto rechableWithout = GetAccessibleLocations(locsToCheck); + const auto rechableWithout = ReachabilitySearch(locsToCheck); ctx->GetItemLocation(excludedCheck)->SetPlacedItem(originalItem); if (resetAfter){ //if resetAfter is on, reset logic we are done @@ -405,8 +405,8 @@ static bool CreateHint(RandomizerCheck location, uint8_t copies, HintType type, //get a gossip stone accessible without the hinted item std::vector gossipStoneLocations = GetAccessibleGossipStones(location); - if (gossipStoneLocations.empty()) { - SPDLOG_DEBUG("\tNO IN LOGIC GOSSIP STONE\n\n"); + if (gossipStoneLocations.empty()) { + SPDLOG_DEBUG("\tNO IN LOGIC GOSSIP STONE\n\n"); return false; } RandomizerCheck gossipStone = RandomElement(gossipStoneLocations); @@ -670,7 +670,7 @@ void CreateStoneHints() { //Getting gossip stone locations temporarily sets one location to not be reachable. //Call the function one last time to get rid of false positives on locations not //being reachable. - GetAccessibleLocations({}); + ReachabilitySearch({}); } std::vector FindItemsAndMarkHinted(std::vector items, std::vector hintChecks){ @@ -681,10 +681,12 @@ std::vector FindItemsAndMarkHinted(std::vector i return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == items[c];}); if (found.size() > 0){ locations.push_back(found[0]); - } - //RANDOTODO make the called functions of this always return true if empty hintChecks are provided - if (hintChecks.size() == 0 || (!ctx->GetItemLocation(found[0])->IsAHintAccessible() && IsReachableWithout(hintChecks,found[0],true))){ - ctx->GetItemLocation(found[0])->SetHintAccesible(); + //RANDOTODO make the called functions of this always return true if empty hintChecks are provided + if (!ctx->GetItemLocation(found[0])->IsAHintAccessible() && (hintChecks.size() == 0 || IsReachableWithout(hintChecks, found[0],true))){ + ctx->GetItemLocation(found[0])->SetHintAccesible(); + } + } else { + locations.push_back(RC_UNKNOWN_CHECK); } } return locations; @@ -730,10 +732,15 @@ void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData){ Option option = ctx->GetOption(staticData.setting); if ((std::holds_alternative(staticData.condition) && option.Is(std::get(staticData.condition))) || (std::holds_alternative(staticData.condition) && option.Is(std::get(staticData.condition)))){ + std::vector locations = {}; if (staticData.targetItems.size() > 0){ locations = FindItemsAndMarkHinted(staticData.targetItems, staticData.hintChecks); } + for(auto check: staticData.targetChecks){ + ctx->GetItemLocation(check)->SetHintAccesible(); + } + //hintKeys are defaulted to in the hint object and do not need to be specified ctx->AddHint(hint, Hint(hint, staticData.type, {}, locations, {}, {}, staticData.yourPocket, staticData.num)); } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index f7250e17ddf..464995df7cd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -613,7 +613,7 @@ static void PlaceVanillaCowMilk() { static void PlaceVanillaOverworldFish() { auto ctx = Rando::Context::GetInstance(); - for (auto rc : Rando::StaticData::overworldFishLocations) { + for (auto rc : Rando::StaticData::GetOverworldFishLocations()) { ctx->PlaceItemInLocation(rc, RG_FISH, false, true); } } @@ -830,7 +830,7 @@ void GenerateItemPool() { } // 9 grotto fish, 5 zora's domain fish if (fsMode.Is(RO_FISHSANITY_OVERWORLD) || fsMode.Is(RO_FISHSANITY_BOTH)) { - for (uint8_t i = 0; i < Rando::StaticData::overworldFishLocations.size(); i++) + for (uint8_t i = 0; i < Rando::StaticData::GetOverworldFishLocations().size(); i++) AddItemToMainPool(GetJunkItem()); } else { PlaceVanillaOverworldFish(); @@ -936,11 +936,11 @@ void GenerateItemPool() { }; if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, Category::cSkulltula)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { ctx->PlaceItemInLocation(loc, RG_GOLD_SKULLTULA_TOKEN, false, true); } } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, Category::cSkulltula)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { if (Rando::StaticData::GetLocation(loc)->IsOverworld()) { ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); } else { @@ -948,7 +948,7 @@ void GenerateItemPool() { } } } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, Category::cSkulltula)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { if (Rando::StaticData::GetLocation(loc)->IsDungeon()) { ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); } else { @@ -1159,9 +1159,15 @@ void GenerateItemPool() { } //Shopsanity - if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_ZERO_ITEMS)) { + if ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) + ) + ) { AddItemsToPool(ItemPool, normalRupees); - } else { //Shopsanity 1-4, random + } else { AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 29b3cb2177c..e15245d13d6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -7,6 +7,7 @@ #include "spoiler_log.hpp" #include "../trial.h" #include "../entrance.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include @@ -24,13 +25,12 @@ bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const { time = true; age = true; - logic->UpdateHelpers(); return GetConditionsMet(); } bool LocationAccess::ConditionsMet() const { - Area* parentRegion = AreaTable(Rando::Context::GetInstance()->GetItemLocation(location)->GetParentRegionKey()); + Region* parentRegion = RegionTable(Rando::Context::GetInstance()->GetItemLocation(location)->GetParentRegionKey()); bool conditionsMet = false; if ((parentRegion->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || @@ -46,20 +46,20 @@ bool LocationAccess::ConditionsMet() const { bool LocationAccess::CanBuy() const { auto ctx = Rando::Context::GetInstance(); //Not a shop or scrub location, don't need to check if buyable - if (!(Rando::StaticData::GetLocation(location)->IsCategory(Category::cShop)) && !(Rando::StaticData::GetLocation(location)->IsCategory(Category::cDekuScrub))) { + if (Rando::StaticData::GetLocation(location)->GetRCType() != RCTYPE_SHOP && Rando::StaticData::GetLocation(location)->GetRCType() != RCTYPE_SCRUB) { return true; } //Check if wallet is large enough to buy item bool SufficientWallet = true; if (ctx->GetItemLocation(location)->GetPrice() > 500) { - SufficientWallet = logic->ProgressiveWallet >= 4; + SufficientWallet = logic->HasItem(RG_TYCOON_WALLET); } else if (ctx->GetItemLocation(location)->GetPrice() > 200) { - SufficientWallet = logic->ProgressiveWallet >= 3; + SufficientWallet = logic->HasItem(RG_GIANT_WALLET); } else if (ctx->GetItemLocation(location)->GetPrice() > 99) { - SufficientWallet = logic->ProgressiveWallet >= 2; + SufficientWallet = logic->HasItem(RG_ADULT_WALLET); } else if (ctx->GetItemLocation(location)->GetPrice() > 0) { - SufficientWallet = logic->ProgressiveWallet >= 1; + SufficientWallet = logic->HasItem(RG_CHILD_WALLET); } bool OtherCondition = true; @@ -67,14 +67,14 @@ bool LocationAccess::CanBuy() const { //Need bottle to buy bottle items, only logically relevant bottle items included here if (placed == RG_BUY_BLUE_FIRE || placed == RG_BUY_BOTTLE_BUG || placed == RG_BUY_FISH || placed == RG_BUY_FAIRYS_SPIRIT) { - OtherCondition = logic->HasBottle; + OtherCondition = logic->HasBottle(); } return SufficientWallet && OtherCondition; } -Area::Area() = default; -Area::Area(std::string regionName_, std::string scene_, RandomizerArea area, +Region::Region() = default; +Region::Region(std::string regionName_, std::string scene_, RandomizerArea area, bool timePass_, std::vector events_, std::vector locations_, @@ -87,28 +87,30 @@ Area::Area(std::string regionName_, std::string scene_, RandomizerArea area, locations(std::move(locations_)), exits(std::move(exits_)) {} -Area::~Area() = default; +Region::~Region() = default; -bool Area::UpdateEvents(SearchMode mode) { - - if (timePass && mode != SearchMode::TimePassAccess) { +bool Region::UpdateEvents(bool haveTimeAccess) { + if (timePass && haveTimeAccess) { + StartPerformanceTimer(PT_TOD_ACCESS); if (Child()) { childDay = true; childNight = true; - AreaTable(RR_ROOT)->childDay = true; - AreaTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->childNight = true; } if (Adult()) { adultDay = true; adultNight = true; - AreaTable(RR_ROOT)->adultDay = true; - AreaTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultNight = true; } + StopPerformanceTimer(PT_TOD_ACCESS); } bool eventsUpdated = false; - + StartPerformanceTimer(PT_EVENT_ACCESS); for (EventAccess& event : events) { + //If the event has already happened, there's no reason to check it if (event.GetEvent()) { continue; @@ -122,21 +124,22 @@ bool Area::UpdateEvents(SearchMode mode) { eventsUpdated = true; } } + StopPerformanceTimer(PT_EVENT_ACCESS); return eventsUpdated; } -void Area::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) { +void Region::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) { Rando::Entrance newExit = Rando::Entrance(newExitKey, {condition}); newExit.SetParentRegion(parentKey); exits.push_front(newExit); } -//The exit will be completely removed from this area -void Area::RemoveExit(Rando::Entrance* exitToRemove) { +//The exit will be completely removed from this region +void Region::RemoveExit(Rando::Entrance* exitToRemove) { exits.remove_if([exitToRemove](const auto exit){return &exit == exitToRemove;}); } -void Area::SetAsPrimary(RandomizerRegion exitToBePrimary) { +void Region::SetAsPrimary(RandomizerRegion exitToBePrimary) { for (auto& exit : exits) { if (exit.Getuint32_t() == exitToBePrimary) { exit.SetAsPrimary(); @@ -145,22 +148,22 @@ void Area::SetAsPrimary(RandomizerRegion exitToBePrimary) { } } -Rando::Entrance* Area::GetExit(RandomizerRegion exitToReturn) { +Rando::Entrance* Region::GetExit(RandomizerRegion exitToReturn) { for (auto& exit : exits) { if (exit.Getuint32_t() == exitToReturn) { return &exit; } } - //auto message = "ERROR: EXIT " + AreaTable(exitToReturn)->regionName + " DOES NOT EXIST IN " + this->regionName; + //auto message = "ERROR: EXIT " + RegionTable(exitToReturn)->regionName + " DOES NOT EXIST IN " + this->regionName; //CitraPrint(message); return nullptr; } -bool Area::CanPlantBeanCheck() const { - return Rando::Context::GetInstance()->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck(); +bool Region::CanPlantBeanCheck() const { + return Rando::Context::GetInstance()->GetLogic()->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck(); } -bool Area::AllAccountedFor() const { +bool Region::AllAccountedFor() const { for (const EventAccess& event : events) { if (!event.GetEvent()) { return false; @@ -182,7 +185,7 @@ bool Area::AllAccountedFor() const { return AllAccess(); } -bool Area::CheckAllAccess(const RandomizerRegion exitKey) { +bool Region::CheckAllAccess(const RandomizerRegion exitKey) { if (!AllAccess()) { return false; } @@ -198,7 +201,7 @@ bool Area::CheckAllAccess(const RandomizerRegion exitKey) { return false; } -void Area::ResetVariables() { +void Region::ResetVariables() { childDay = false; childNight = false; adultDay = false; @@ -209,133 +212,133 @@ void Area::ResetVariables() { } } -std::array areaTable; +std::array areaTable; -bool Here(const RandomizerRegion area, ConditionFn condition) { - return areaTable[area].HereCheck(condition); +bool Here(const RandomizerRegion region, ConditionFn condition) { + return areaTable[region].Here(condition); } -bool CanPlantBean(const RandomizerRegion area) { - return areaTable[area].CanPlantBeanCheck(); +bool CanPlantBean(const RandomizerRegion region) { + return areaTable[region].CanPlantBeanCheck(); } -bool BothAges(const RandomizerRegion area) { - return areaTable[area].BothAgesCheck(); +bool BothAges(const RandomizerRegion region) { + return areaTable[region].BothAgesCheck(); } -bool ChildCanAccess(const RandomizerRegion area) { - return areaTable[area].Child(); +bool ChildCanAccess(const RandomizerRegion region) { + return areaTable[region].Child(); } -bool AdultCanAccess(const RandomizerRegion area) { - return areaTable[area].Adult(); +bool AdultCanAccess(const RandomizerRegion region) { + return areaTable[region].Adult(); } -bool HasAccessTo(const RandomizerRegion area) { - return areaTable[area].HasAccess(); +bool HasAccessTo(const RandomizerRegion region) { + return areaTable[region].HasAccess(); } -Rando::Context* randoCtx; +Rando::Context* ctx; std::shared_ptr logic; -void AreaTable_Init() { +void RegionTable_Init() { using namespace Rando; - randoCtx = Context::GetInstance().get(); - logic = randoCtx->GetLogic(); + ctx = Context::GetInstance().get(); + logic = ctx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow grottoEvents = { - EventAccess(&logic->GossipStoneFairy, { [] { return logic->GossipStoneFairy || logic->CanSummonGossipFairy; } }), + EventAccess(&logic->GossipStoneFairy, { [] { return logic->CallGossipFairy(); } }), EventAccess(&logic->ButterflyFairy, { [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); } }), - EventAccess(&logic->BugShrub, { [] { return logic->CanCutShrubs; } }), + EventAccess(&logic->BugShrub, { [] { return logic->CanCutShrubs(); } }), EventAccess(&logic->LoneFish, { [] { 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. - areaTable.fill(Area("Invalid Area", "Invalid Area", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, {})); + areaTable.fill(Region("Invalid Region", "Invalid Region", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, {})); //name, scene, hint text, events, locations, exits - areaTable[RR_ROOT] = Area("Root", "", RA_LINKS_POCKET, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ROOT] = Region("Root", "", RA_LINKS_POCKET, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_LINKS_POCKET, true), - LOCATION(RC_TRIFORCE_COMPLETED, logic->CanCompleteTriforce), + LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Value();), LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)), }, { //Exits Entrance(RR_ROOT_EXITS, {[]{return true;}}) }); - areaTable[RR_ROOT_EXITS] = Area("Root Exits", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_CHILD_SPAWN, {[]{return logic->IsChild;}}), Entrance(RR_ADULT_SPAWN, {[]{return logic->IsAdult;}}), Entrance(RR_MINUET_OF_FOREST_WARP, {[]{return logic->CanUse(RG_MINUET_OF_FOREST);}}), - Entrance(RR_BOLERO_OF_FIRE_WARP, {[]{return logic->CanUse(RG_BOLERO_OF_FIRE) && logic->CanLeaveForest;}}), - Entrance(RR_SERENADE_OF_WATER_WARP, {[]{return logic->CanUse(RG_SERENADE_OF_WATER) && logic->CanLeaveForest;}}), - Entrance(RR_NOCTURNE_OF_SHADOW_WARP, {[]{return logic->CanUse(RG_NOCTURNE_OF_SHADOW) && logic->CanLeaveForest;}}), - Entrance(RR_REQUIEM_OF_SPIRIT_WARP, {[]{return logic->CanUse(RG_REQUIEM_OF_SPIRIT) && logic->CanLeaveForest;}}), - Entrance(RR_PRELUDE_OF_LIGHT_WARP, {[]{return logic->CanUse(RG_PRELUDE_OF_LIGHT) && logic->CanLeaveForest;}}), + Entrance(RR_BOLERO_OF_FIRE_WARP, {[]{return logic->CanUse(RG_BOLERO_OF_FIRE) && logic->CanLeaveForest();}}), + Entrance(RR_SERENADE_OF_WATER_WARP, {[]{return logic->CanUse(RG_SERENADE_OF_WATER) && logic->CanLeaveForest();}}), + Entrance(RR_NOCTURNE_OF_SHADOW_WARP, {[]{return logic->CanUse(RG_NOCTURNE_OF_SHADOW) && logic->CanLeaveForest();}}), + Entrance(RR_REQUIEM_OF_SPIRIT_WARP, {[]{return logic->CanUse(RG_REQUIEM_OF_SPIRIT) && logic->CanLeaveForest();}}), + Entrance(RR_PRELUDE_OF_LIGHT_WARP, {[]{return logic->CanUse(RG_PRELUDE_OF_LIGHT) && logic->CanLeaveForest();}}), }); - areaTable[RR_CHILD_SPAWN] = Area("Child Spawn", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_CHILD_SPAWN] = Region("Child Spawn", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KF_LINKS_HOUSE, {[]{return true;}}), }); - areaTable[RR_ADULT_SPAWN] = Area("Adult Spawn", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ADULT_SPAWN] = Region("Adult Spawn", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[RR_MINUET_OF_FOREST_WARP] = Area("Minuet of Forest Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_MINUET_OF_FOREST_WARP] = Region("Minuet of Forest Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[RR_BOLERO_OF_FIRE_WARP] = Area("Bolero of Fire Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_BOLERO_OF_FIRE_WARP] = Region("Bolero of Fire Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}), }); - areaTable[RR_SERENADE_OF_WATER_WARP] = Area("Serenade of Water Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SERENADE_OF_WATER_WARP] = Region("Serenade of Water Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - areaTable[RR_REQUIEM_OF_SPIRIT_WARP] = Area("Requiem of Spirit Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_REQUIEM_OF_SPIRIT_WARP] = Region("Requiem of Spirit Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[RR_NOCTURNE_OF_SHADOW_WARP] = Area("Nocturne of Shadow Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_NOCTURNE_OF_SHADOW_WARP] = Region("Nocturne of Shadow Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), }); - areaTable[RR_PRELUDE_OF_LIGHT_WARP] = Area("Prelude of Light Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_PRELUDE_OF_LIGHT_WARP] = Region("Prelude of Light Warp", "", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); // Overworld - AreaTable_Init_LostWoods(); - AreaTable_Init_HyruleField(); - AreaTable_Init_CastleTown(); - AreaTable_Init_Kakariko(); - AreaTable_Init_DeathMountain(); - AreaTable_Init_ZorasDomain(); - AreaTable_Init_GerudoValley(); + RegionTable_Init_LostWoods(); + RegionTable_Init_HyruleField(); + RegionTable_Init_CastleTown(); + RegionTable_Init_Kakariko(); + RegionTable_Init_DeathMountain(); + RegionTable_Init_ZorasDomain(); + RegionTable_Init_GerudoValley(); // Dungeons - AreaTable_Init_DekuTree(); - AreaTable_Init_DodongosCavern(); - AreaTable_Init_JabuJabusBelly(); - AreaTable_Init_ForestTemple(); - AreaTable_Init_FireTemple(); - AreaTable_Init_WaterTemple(); - AreaTable_Init_SpiritTemple(); - AreaTable_Init_ShadowTemple(); - AreaTable_Init_BottomOfTheWell(); - AreaTable_Init_IceCavern(); - AreaTable_Init_GerudoTrainingGrounds(); - AreaTable_Init_GanonsCastle(); + RegionTable_Init_DekuTree(); + RegionTable_Init_DodongosCavern(); + RegionTable_Init_JabuJabusBelly(); + RegionTable_Init_ForestTemple(); + RegionTable_Init_FireTemple(); + RegionTable_Init_WaterTemple(); + RegionTable_Init_SpiritTemple(); + RegionTable_Init_ShadowTemple(); + RegionTable_Init_BottomOfTheWell(); + RegionTable_Init_IceCavern(); + RegionTable_Init_GerudoTrainingGrounds(); + RegionTable_Init_GanonsCastle(); //Set parent regions for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) { @@ -390,45 +393,47 @@ void ReplaceAllInString(std::string& s, std::string const& toReplace, std::strin std::string CleanCheckConditionString(std::string condition) { ReplaceAllInString(condition, "logic->", ""); - ReplaceAllInString(condition, "randoCtx->", ""); + ReplaceAllInString(condition, "ctx->", ""); + ReplaceAllInString(condition, ".Value()", ""); + ReplaceAllInString(condition, "GetSaveContext()->", ""); return condition; } -namespace Areas { +namespace Regions { - const auto GetAllAreas() { - static const size_t areaCount = RR_MAX - (RR_NONE + 1); + const auto GetAllRegions() { + static const size_t regionCount = RR_MAX - (RR_NONE + 1); - static std::array allAreas = {}; + static std::array allRegions = {}; static bool intialized = false; if (!intialized) { - for (size_t i = 0; i < areaCount; i++) { - allAreas[i] = (RandomizerRegion)((RR_NONE + 1) + i); + for (size_t i = 0; i < regionCount; i++) { + allRegions[i] = (RandomizerRegion)((RR_NONE + 1) + i); } intialized = true; } - return allAreas; + return allRegions; } void AccessReset() { auto ctx = Rando::Context::GetInstance(); - for (const RandomizerRegion area : GetAllAreas()) { - AreaTable(area)->ResetVariables(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); } if(/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { - AreaTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->childNight = true; } else { - AreaTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultNight = true; } } else { if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { - AreaTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->childDay = true; } else { - AreaTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultDay = true; } } } @@ -436,10 +441,10 @@ namespace Areas { //Reset exits and clear items from locations void ResetAllLocations() { auto ctx = Rando::Context::GetInstance(); - for (const RandomizerRegion area : GetAllAreas()) { - AreaTable(area)->ResetVariables(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); //Erase item from every location in this exit - for (LocationAccess& locPair : AreaTable(area)->locations) { + for (LocationAccess& locPair : RegionTable(region)->locations) { RandomizerCheck location = locPair.GetLocation(); Rando::Context::GetInstance()->GetItemLocation(location)->ResetVariables(); } @@ -447,23 +452,23 @@ namespace Areas { if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { - AreaTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->childNight = true; } else { - AreaTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultNight = true; } } else { if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { - AreaTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->childDay = true; } else { - AreaTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultDay = true; } } } bool HasTimePassAccess(uint8_t age) { - for (const RandomizerRegion areaKey : GetAllAreas()) { - auto area = AreaTable(areaKey); - if (area->timePass && ((age == RO_AGE_CHILD && area->Child()) || (age == RO_AGE_ADULT && area->Adult()))) { + for (const RandomizerRegion regionKey : GetAllRegions()) { + auto region = RegionTable(regionKey); + if (region->timePass && ((age == RO_AGE_CHILD && region->Child()) || (age == RO_AGE_ADULT && region->Adult()))) { return true; } } @@ -479,24 +484,24 @@ namespace Areas { worldGraph.open (str + ".dot"); worldGraph << "digraph {\n\tcenter=true;\n"; - for (const RandomizerRegion areaKey : GetAllAreas()) { - auto area = AreaTable(areaKey); - for (auto exit : area->exits) { - if (exit.GetConnectedRegion()->regionName != "Invalid Area") { + for (const RandomizerRegion regionKey : GetAllRegions()) { + auto region = RegionTable(regionKey); + for (auto exit : region->exits) { + if (exit.GetConnectedRegion()->regionName != "Invalid Region") { std::string parent = exit.GetParentRegion()->regionName; - if (area->childDay) { + if (region->childDay) { parent += " CD"; } - if (area->childNight) { + if (region->childNight) { parent += " CN"; } - if (area->adultDay) { + if (region->adultDay) { parent += " AD"; } - if (area->adultNight) { + if (region->adultNight) { parent += " AN"; } - Area* connected = exit.GetConnectedRegion(); + Region* connected = exit.GetConnectedRegion(); auto connectedStr = connected->regionName; if (connected->childDay) { connectedStr += " CD"; @@ -520,20 +525,20 @@ namespace Areas { worldGraph.close(); } -} //namespace Areas +} //namespace Regions -Area* AreaTable(const RandomizerRegion areaKey) { - if (areaKey > RR_MAX) { +Region* RegionTable(const RandomizerRegion regionKey) { + if (regionKey > RR_MAX) { printf("\x1b[1;1HERROR: AREAKEY TOO BIG"); } - return &(areaTable[areaKey]); + return &(areaTable[regionKey]); } //Retrieve all the shuffable entrances of a specific type std::vector GetShuffleableEntrances(Rando::EntranceType type, bool onlyPrimary /*= true*/) { std::vector entrancesToShuffle = {}; - for (RandomizerRegion area : Areas::GetAllAreas()) { - for (auto& exit : AreaTable(area)->exits) { + for (RandomizerRegion region : Regions::GetAllRegions()) { + for (auto& exit : RegionTable(region)->exits) { if ((exit.GetType() == type || type == Rando::EntranceType::All) && (exit.IsPrimary() || !onlyPrimary) && exit.GetType() != Rando::EntranceType::None) { entrancesToShuffle.push_back(&exit); } @@ -544,8 +549,8 @@ std::vector GetShuffleableEntrances(Rando::EntranceType type, // Get the specific entrance by name Rando::Entrance* GetEntrance(const std::string name) { - for (RandomizerRegion area : Areas::GetAllAreas()) { - for (auto& exit : AreaTable(area)->exits) { + for (RandomizerRegion region : Regions::GetAllRegions()) { + for (auto& exit : RegionTable(region)->exits) { if (exit.GetName() == name) { return &exit; } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index 286551cab11..2b18ab02961 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -12,7 +12,7 @@ typedef bool (*ConditionFn)(); // I hate this but every alternative I can think of right now is worse -extern Rando::Context* randoCtx; +extern Rando::Context* ctx; extern std::shared_ptr logic; class EventAccess { @@ -53,7 +53,6 @@ class EventAccess { time = true; age = true; - logic->UpdateHelpers(); return ConditionsMet(); } @@ -136,15 +135,15 @@ namespace Rando { enum class EntranceType; } -class Area { +class Region { public: - Area(); - Area(std::string regionName_, std::string scene_, RandomizerArea area, + Region(); + Region(std::string regionName_, std::string scene_, RandomizerArea area, bool timePass_, std::vector events_, std::vector locations_, std::list exits_); - ~Area(); + ~Region(); std::string regionName; std::string scene; @@ -164,9 +163,9 @@ class Area { bool childNight = false; bool adultDay = false; bool adultNight = false; - bool addedToPool = false; + bool addedToPool = false;; - bool UpdateEvents(SearchMode mode); + bool UpdateEvents(bool haveTimeAccess = true); void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); @@ -211,7 +210,7 @@ class Area { //access to this area. For example: if there are rocks that block a path //which both child and adult can access, adult having hammer can give //both child and adult access to the path. - bool HereCheck(ConditionFn condition) { + bool Here(ConditionFn condition) { //store current age variables bool pastAdult = logic->IsAdult; @@ -221,14 +220,12 @@ class Area { logic->IsChild = Child(); logic->IsAdult = Adult(); - //update helpers and check condition as well as having at least child or adult access - logic->UpdateHelpers(); + //heck condition as well as having at least child or adult access bool hereVal = condition() && (logic->IsAdult || logic->IsChild); //set back age variables logic->IsChild = pastChild; logic->IsAdult = pastAdult; - logic->UpdateHelpers(); return hereVal; } @@ -246,20 +243,20 @@ class Area { } }; -extern std::array areaTable; +extern std::array areaTable; extern std::vector grottoEvents; -bool Here(const RandomizerRegion area, ConditionFn condition); -bool CanPlantBean(const RandomizerRegion area); -bool BothAges(const RandomizerRegion area); -bool ChildCanAccess(const RandomizerRegion area); -bool AdultCanAccess(const RandomizerRegion area); -bool HasAccessTo(const RandomizerRegion area); +bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this +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); #define DAY_NIGHT_CYCLE true #define NO_DAY_NIGHT_CYCLE false -namespace Areas { +namespace Regions { extern void AccessReset(); extern void ResetAllLocations(); @@ -267,29 +264,29 @@ namespace Areas { extern void DumpWorldGraph(std::string str); } //namespace Exits -void AreaTable_Init(); -Area* AreaTable(const RandomizerRegion areaKey); +void RegionTable_Init(); +Region* RegionTable(const RandomizerRegion regionKey); std::vector GetShuffleableEntrances(Rando::EntranceType type, bool onlyPrimary = true); Rando::Entrance* GetEntrance(const std::string name); // Overworld -void AreaTable_Init_LostWoods(); -void AreaTable_Init_HyruleField(); -void AreaTable_Init_CastleTown(); -void AreaTable_Init_Kakariko(); -void AreaTable_Init_DeathMountain(); -void AreaTable_Init_ZorasDomain(); -void AreaTable_Init_GerudoValley(); +void RegionTable_Init_LostWoods(); +void RegionTable_Init_HyruleField(); +void RegionTable_Init_CastleTown(); +void RegionTable_Init_Kakariko(); +void RegionTable_Init_DeathMountain(); +void RegionTable_Init_ZorasDomain(); +void RegionTable_Init_GerudoValley(); // Dungeons -void AreaTable_Init_DekuTree(); -void AreaTable_Init_DodongosCavern(); -void AreaTable_Init_JabuJabusBelly(); -void AreaTable_Init_ForestTemple(); -void AreaTable_Init_FireTemple(); -void AreaTable_Init_WaterTemple(); -void AreaTable_Init_SpiritTemple(); -void AreaTable_Init_ShadowTemple(); -void AreaTable_Init_BottomOfTheWell(); -void AreaTable_Init_IceCavern(); -void AreaTable_Init_GerudoTrainingGrounds(); -void AreaTable_Init_GanonsCastle(); +void RegionTable_Init_DekuTree(); +void RegionTable_Init_DodongosCavern(); +void RegionTable_Init_JabuJabusBelly(); +void RegionTable_Init_ForestTemple(); +void RegionTable_Init_FireTemple(); +void RegionTable_Init_WaterTemple(); +void RegionTable_Init_SpiritTemple(); +void RegionTable_Init_ShadowTemple(); +void RegionTable_Init_BottomOfTheWell(); +void RegionTable_Init_IceCavern(); +void RegionTable_Init_GerudoTrainingGrounds(); +void RegionTable_Init_GanonsCastle(); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp index 44260c7ebe4..2e238622f96 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_bottom_of_the_well.cpp @@ -4,44 +4,44 @@ using namespace Rando; -void AreaTable_Init_BottomOfTheWell() { +void RegionTable_Init_BottomOfTheWell() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_BOTTOM_OF_THE_WELL_ENTRYWAY] = Area("Bottom of the Well Entryway", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_BOTTOM_OF_THE_WELL_ENTRYWAY] = Region("Bottom of the Well Entryway", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && (logic->CanChildAttack || logic->CanUse(RG_NUTS));}}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && (logic->CanAttack() || logic->CanUse(RG_NUTS));}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { - areaTable[RR_BOTTOM_OF_THE_WELL_MAIN_AREA] = Area("Bottom of the Well Main Area", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { + areaTable[RR_BOTTOM_OF_THE_WELL_MAIN_AREA] = Region("Bottom of the Well Main Region", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->StickPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives), - LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives), - LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->Swim || logic->CanUse(RG_ZELDAS_LULLABY)) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->KokiriSword || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)))), - LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_ZELDAS_LULLABY)) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_KOKIRI_SWORD) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)))), + LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), - LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasExplosives || (((logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))) || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_BASEMENT))) && logic->GoronBracelet)), - LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->Boomerang && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->Boomerang && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (randoCtx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Boomerang), + LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasExplosives() || (((logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))) || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))) && logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanUse(RG_BOOMERANG) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanUse(RG_BOOMERANG) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), @@ -51,31 +51,32 @@ void AreaTable_Init_BottomOfTheWell() { /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) { - areaTable[RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Area("Bottom of the Well MQ Perimeter", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) { + //RANDOTODO double check the CanAttacks when rewriting, i assumed CanChildAttack was the only one called because of the initial crawlspace + areaTable[RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Region("Bottom of the Well MQ Perimeter", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { //Events //EventAccess(&WallFairy, {[]{return WallFairy || logic->Slingshot;}}), }, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->KokiriSword || (logic->CanUse(RG_STICKS) && randoCtx->GetTrickOption(RT_BOTW_CHILD_DEADHAND))), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives || (randoCtx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->Boomerang)), - //Trick: logic->HasExplosives || (LogicBotWMQDeadHandKey && logic->Boomerang) - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanChildAttack), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanChildAttack && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND))), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives() || (ctx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->CanUse(RG_BOOMERANG))), + //Trick: logic->HasExplosives() || (LogicBotWMQDeadHandKey && logic->CanUse(RG_BOOMERANG)) + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanAttack()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanAttack() && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (randoCtx->GetTrickOption(RT_BOTW_MQ_PITS) && logic->HasExplosives);}}), - //Trick: logic->CanUse(RG_ZELDAS_LULLABY) || (LogicBotWMQPits && logic->HasExplosives) + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (ctx->GetTrickOption(RT_BOTW_MQ_PITS) && logic->HasExplosives());}}), + //Trick: logic->CanUse(RG_ZELDAS_LULLABY) || (LogicBotWMQPits && logic->HasExplosives()) }); - areaTable[RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE] = Area("Bottom of the Well MQ Middle", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE] = Region("Bottom of the Well MQ Middle", "Bottom of the Well", RA_BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, true), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->HasExplosives && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->HasExplosives() && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, true), - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->CanChildAttack && (randoCtx->GetTrickOption(RT_BOTW_MQ_PITS) || logic->HasExplosives)), - //Trick: logic->CanChildAttack && (LogicBotWMQPits || logic->HasExplosives) + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->CanAttack() && (ctx->GetTrickOption(RT_BOTW_MQ_PITS) || logic->HasExplosives())), + //Trick: logic->CanChildAttack && (LogicBotWMQPits || logic->HasExplosives()) }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index e809beb5472..74059abc8f4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp @@ -3,15 +3,15 @@ using namespace Rando; -void AreaTable_Init_CastleTown() { - areaTable[RR_MARKET_ENTRANCE] = Area("Market Entrance", "Market Entrance", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { +void RegionTable_Init_CastleTown() { + areaTable[RR_MARKET_ENTRANCE] = Region("Market Entrance", "Market Entrance", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return logic->IsAdult || logic->AtDay;}}), Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_MARKET_GUARD_HOUSE, {[]{return true;}}), }); - areaTable[RR_THE_MARKET] = Area("Market", "Market", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_THE_MARKET] = Region("Market", "Market", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), Entrance(RR_TOT_ENTRANCE, {[]{return true;}}), @@ -25,7 +25,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_MARKET_BACK_ALLEY, {[]{return logic->IsChild;}}), }); - areaTable[RR_MARKET_BACK_ALLEY] = Area("Market Back Alley", "Market", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_MARKET_BACK_ALLEY] = Region("Market Back Alley", "Market", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_MARKET_BOMBCHU_SHOP, {[]{return logic->AtNight;}}), @@ -33,9 +33,9 @@ void AreaTable_Init_CastleTown() { Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, {[]{return logic->AtNight;}}), }); - areaTable[RR_TOT_ENTRANCE] = Area("ToT Entrance", "ToT Entrance", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_TOT_ENTRANCE] = Region("ToT Entrance", "ToT Entrance", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true), @@ -48,58 +48,58 @@ void AreaTable_Init_CastleTown() { Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[RR_TEMPLE_OF_TIME] = Area("Temple of Time", "Temple of Time", RA_TEMPLE_OF_TIME, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_TEMPLE_OF_TIME] = Region("Temple of Time", "Temple of Time", RA_TEMPLE_OF_TIME, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS), + LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS()), LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild), LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult), LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult), }, { //Exits Entrance(RR_TOT_ENTRANCE, {[]{return true;}}), - Entrance(RR_TOT_BEYOND_DOOR_OF_TIME, {[]{return randoCtx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN) || (logic->CanUse(RG_SONG_OF_TIME) && (randoCtx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY) || (logic->HasAllStones && logic->OcarinaOfTime)));}}), + 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] = Area("Beyond Door of Time", "Beyond Door of Time", RA_TEMPLE_OF_TIME, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_TOT_BEYOND_DOOR_OF_TIME] = Region("Beyond Door of Time", "Beyond Door of Time", RA_TEMPLE_OF_TIME, NO_DAY_NIGHT_CYCLE, { //Events //EventAccess(&logic->TimeTravel, {[]{return true;}}), }, { //Locations LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), LOCATION(RC_GIFT_FROM_SAGES, logic->IsAdult), - LOCATION(RC_SHEIK_AT_TEMPLE, logic->ForestMedallion && logic->IsAdult), + LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult), }, { //Exits Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[RR_CASTLE_GROUNDS] = Area("Castle Grounds", "Castle Grounds", RA_CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", "Castle Grounds", RA_CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), Entrance(RR_HYRULE_CASTLE_GROUNDS, {[]{return logic->IsChild;}}), Entrance(RR_GANONS_CASTLE_GROUNDS, {[]{return logic->IsAdult;}}), }); - areaTable[RR_HYRULE_CASTLE_GROUNDS] = Area("Hyrule Castle Grounds", "Castle Grounds", RA_HYRULE_CASTLE, DAY_NIGHT_CYCLE, { + areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", "Castle Grounds", RA_HYRULE_CASTLE, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations LOCATION(RC_HC_MALON_EGG, true), - LOCATION(RC_HC_GS_TREE, logic->CanChildAttack), + LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()), LOCATION(RC_HC_MALON_GOSSIP_STONE, true), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), }, { //Exits Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), - Entrance(RR_HC_GARDEN, {[]{return logic->WeirdEgg || !randoCtx->GetOption(RSK_SHUFFLE_WEIRD_EGG);}}), - Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->CanBlastOrSmash;}}), - Entrance(RR_HC_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), + Entrance(RR_HC_GARDEN, {[]{return logic->CanUse(RG_WEIRD_EGG) || !ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG);}}), + Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->BlastOrSmash();}}), + Entrance(RR_HC_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_HC_GARDEN] = Area("HC Garden", "Castle Grounds", RA_HYRULE_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HC_GARDEN] = Region("HC Garden", "Castle Grounds", RA_HYRULE_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events }, { //Locations @@ -110,7 +110,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_HYRULE_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Area("HC Great Fairy Fountain", "HC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", "HC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { @@ -118,25 +118,25 @@ void AreaTable_Init_CastleTown() { Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[RR_HC_STORMS_GROTTO] = Area("HC Storms Grotto", "HC Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->CanBlastOrSmash;}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->CanBlastOrSmash && logic->CanSummonGossipFairy);}}), - EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->CanBlastOrSmash;}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->BlastOrSmash();}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CallGossipFairy();}}), + EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->BlastOrSmash();}}), }, { //Locations - LOCATION(RC_HC_GS_STORMS_GROTTO, (logic->CanBlastOrSmash && logic->HookshotOrBoomerang) || (logic->Boomerang && randoCtx->GetTrickOption(RT_HC_STORMS_GS))), - LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, logic->CanBlastOrSmash), + LOCATION(RC_HC_GS_STORMS_GROTTO, (logic->BlastOrSmash() && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS))), + LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, logic->BlastOrSmash()), }, { //Exits Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[RR_GANONS_CASTLE_GROUNDS] = Area("Ganon's Castle Grounds", "Castle Grounds", RA_OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { - EventAccess(&logic->BuiltRainbowBridge, {[]{return logic->CanBuildRainbowBridge;}}), + areaTable[RR_GANONS_CASTLE_GROUNDS] = Region("Ganon's Castle Grounds", "Castle Grounds", RA_OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + EventAccess(&logic->BuiltRainbowBridge, {[]{return logic->CanBuildRainbowBridge();}}), }, { - //Locations //the terrain was lowered such that you can't get this GS with a simple sword slash - LOCATION(RC_OGC_GS, logic->CanJumpslash || logic->CanUseProjectile || (logic->CanShield && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + //Locations + LOCATION(RC_OGC_GS, logic->CanJumpslash() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, {[]{return logic->AtNight;}}), @@ -144,7 +144,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_GANONS_CASTLE_LEDGE, {[]{return logic->BuiltRainbowBridge;}}), }); - areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Area("OGC Great Fairy Fountain", "OGC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", "OGC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { @@ -152,20 +152,23 @@ void AreaTable_Init_CastleTown() { Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE] = Area("Castle Grounds From Ganon's Castle", "Castle Grounds From Ganon's Castle", RA_CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE] = Region("Castle Grounds From Ganon's Castle", "Castle Grounds From Ganon's Castle", RA_CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(RR_HYRULE_CASTLE_GROUNDS, { [] { return logic->IsChild; }}), Entrance(RR_GANONS_CASTLE_LEDGE, { [] { return logic->IsAdult; }}), }); - areaTable[RR_GANONS_CASTLE_LEDGE] = Area("Ganon's Castle Ledge", "OGC Ganon's Castle Ledge", RA_OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_GANONS_CASTLE_LEDGE] = Region("Ganon's Castle Ledge", "OGC Ganon's Castle Ledge", RA_OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(RR_GANONS_CASTLE_GROUNDS, {[]{return logic->BuiltRainbowBridge;}}), Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return logic->IsAdult;}}), }); - areaTable[RR_MARKET_GUARD_HOUSE] = Area("Market Guard House", "Market Guard House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", "Market Guard House", RA_NONE, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->CanEmptyBigPoes, {[]{return logic->IsAdult;}}), + }, { //Locations LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), @@ -174,7 +177,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), }); - areaTable[RR_MARKET_BAZAAR] = Area("Market Bazaar", "Market Bazaar", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", "Market Bazaar", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_MARKET_BAZAAR_ITEM_1, true), LOCATION(RC_MARKET_BAZAAR_ITEM_2, true), @@ -189,10 +192,10 @@ void AreaTable_Init_CastleTown() { Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_MASK_SHOP] = Area("Market Mask Shop", "Market Mask Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", "Market Mask Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->SkullMask, {[]{return logic->SkullMask || (logic->ZeldasLetter && (randoCtx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link'd pocket - EventAccess(&logic->MaskOfTruth, {[]{return logic->MaskOfTruth || (logic->SkullMask && (randoCtx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && AreaTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->HasAllStones)));}}), + EventAccess(&logic->SkullMask, {[]{return logic->SkullMask || (logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket + EventAccess(&logic->MaskOfTruth, {[]{return logic->MaskOfTruth || (logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3)));}}), }, { LOCATION(RC_MASK_SHOP_HINT, true), }, { @@ -200,27 +203,27 @@ void AreaTable_Init_CastleTown() { Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_SHOOTING_GALLERY] = Area("Market Shooting Gallery", "Market Shooting Gallery", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_SHOOTING_GALLERY] = Region("Market Shooting Gallery", "Market Shooting Gallery", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->ChildsWallet), + LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)), }, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_BOMBCHU_BOWLING] = Area("Market Bombchu Bowling", "Market Bombchu Bowling", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", "Market Bombchu Bowling", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->CouldPlayBowling, {[]{return (logic->ChildsWallet);}}), + EventAccess(&logic->CouldPlayBowling, {[]{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->CouldPlayBowling && logic->BombchusEnabled()), + LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), }, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_POTION_SHOP] = Area("Market Potion Shop", "Market Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", "Market Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, true), LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, true), @@ -235,26 +238,26 @@ void AreaTable_Init_CastleTown() { Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Area("Market Treasure Chest Game", "Market Treasure Chest Game", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", "Market Treasure Chest Game", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GREG_HINT, true), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->ChildsWallet && ((logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (randoCtx->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->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->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(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)))), }, { //Exits Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[RR_MARKET_BOMBCHU_SHOP] = Area("Market Bombchu Shop", "Market Bombchu Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", "Market Bombchu Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, true), LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, true), @@ -269,7 +272,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); - areaTable[RR_MARKET_DOG_LADY_HOUSE] = Area("Market Dog Lady House", "Market Dog Lady House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", "Market Dog Lady House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), }, { @@ -277,7 +280,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); - areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Area("Market Man in Green House", "Market Man in Green House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Region("Market Man in Green House", "Market Man in Green House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index 73284dbc8f5..b61687d3d16 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp @@ -3,76 +3,75 @@ using namespace Rando; -void AreaTable_Init_DeathMountain() { - auto ctx = Rando::Context::GetInstance(); - areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Area("Death Mountain", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { +void RegionTable_Init_DeathMountain() { + areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives || logic->GoronBracelet));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)));}}), }, { //Locations - LOCATION(RC_DMT_CHEST, logic->CanBlastOrSmash || (randoCtx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->GoronBracelet)), - LOCATION(RC_DMT_FREESTANDING_POH, logic->CanTakeDamage || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives || logic->GoronBracelet))), - LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanPlantBugs && (logic->HasExplosives || logic->GoronBracelet || (randoCtx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->CanTakeDamage || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), - LOCATION(RC_DMT_GS_NEAR_KAK, logic->CanBlastOrSmash), - LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (randoCtx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (randoCtx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (randoCtx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || randoCtx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS), + LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), + 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()), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}), Entrance(RR_GORON_CITY, {[]{return true;}}), - Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->CanBlastOrSmash;}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->GoronBracelet) || (logic->HoverBoots && randoCtx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}}), - Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return logic->HasExplosives || logic->GoronBracelet || logic->IsAdult;}}), - Entrance(RR_DMT_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}}), + Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}}), + Entrance(RR_DMT_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Area("Death Mountain Summit", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { + areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->PrescriptionAccess, {[]{return logic->PrescriptionAccess || (logic->IsAdult && (logic->BrokenSwordAccess || logic->BrokenSword));}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->PrescriptionAccess, {[]{return logic->PrescriptionAccess || (logic->IsAdult && (logic->BrokenSwordAccess || logic->CanUse(RG_BROKEN_SWORD)));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->BrokenSword), - LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->Eyedrops), - LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->ClaimCheck), - LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || randoCtx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS), + LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), + LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)), + LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), + LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), Entrance(RR_DMT_OWL_FLIGHT, {[]{return logic->IsChild;}}), - Entrance(RR_DMT_COW_GROTTO, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->CanBlastOrSmash;});}}), + Entrance(RR_DMT_COW_GROTTO, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}}), }); - areaTable[RR_DMT_OWL_FLIGHT] = Area("DMT Owl Flight", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DMT_OWL_FLIGHT] = Region("DMT Owl Flight", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return true;}}), }); - areaTable[RR_DMT_COW_GROTTO] = Area("DMT Cow Grotto", "DMT Cow Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", "DMT Cow Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives), + LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), }); - areaTable[RR_DMT_STORMS_GROTTO] = Area("DMT Storms Grotto", "DMT Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", "DMT Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), - LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); - areaTable[RR_DMT_GREAT_FAIRY_FOUNTAIN] = Area("DMT Great Fairy Fountain", "DMT Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMT_GREAT_FAIRY_FOUNTAIN] = Region("DMT Great Fairy Fountain", "DMT Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { @@ -80,47 +79,47 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), }); - areaTable[RR_GORON_CITY] = Area("Goron City", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GORON_CITY] = Region("Goron City", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), - EventAccess(&logic->BugRock, {[]{return logic->BugRock || (logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS));}}), + EventAccess(&logic->BugRock, {[]{return logic->BugRock || (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS));}}), EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}}), - EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->CanBlastOrSmash || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->GoronBracelet || logic->GoronCityChildFire);}}), + EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire);}}), EventAccess(&logic->GCDaruniasDoorOpenChild, {[]{return logic->GCDaruniasDoorOpenChild || (logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY));}}), - EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->GoronBracelet || logic->HasExplosives || logic->Bow || (randoCtx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}}), + EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (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))));}}), }, { //Locations - LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (randoCtx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->Bombs || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_GC_POT)))), - LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives || (logic->GoronBracelet && randoCtx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), + 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_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_GS_BOULDER_MAZE, logic->IsChild && logic->CanBlastOrSmash), - LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->CanAdultAttack), - LOCATION(RC_GC_MEDIGORON, logic->IsAdult && logic->AdultsWallet && (logic->CanBlastOrSmash || logic->GoronBracelet)), - LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->CanBlastOrSmash || logic->GoronBracelet), + 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->HasItem(RG_ADULT_WALLET) && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), Entrance(RR_GC_WOODS_WARP, {[]{return logic->GCWoodsWarpOpen;}}), - Entrance(RR_GC_SHOP, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->CanBlastOrSmash || logic->GoronBracelet || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}}), + 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_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) && randoCtx->GetTrickOption(RT_GC_GROTTO)));}}), + 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)));}}), }); - areaTable[RR_GC_WOODS_WARP] = Area("GC Woods Warp", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->CanBlastOrSmash || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits - Entrance(RR_GORON_CITY, {[]{return logic->CanLeaveForest && logic->GCWoodsWarpOpen;}}), + Entrance(RR_GORON_CITY, {[]{return logic->CanLeaveForest() && logic->GCWoodsWarpOpen;}}), Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), }); - areaTable[RR_GC_DARUNIAS_CHAMBER] = Area("GC Darunias Chamber", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GC_DARUNIAS_CHAMBER] = Region("GC Darunias Chamber", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_STICKS));}}), }, { @@ -132,13 +131,13 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->IsAdult;}}), }); - areaTable[RR_GC_GROTTO_PLATFORM] = Area("GC Grotto Platform", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GC_GROTTO_PLATFORM] = Region("GC Grotto Platform", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GC_GROTTO, {[]{return true;}}), - Entrance(RR_GORON_CITY, {[]{return logic->EffectiveHealth > 2 || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_NAYRUS_LOVE) || ((logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_GORON_CITY, {[]{return logic->EffectiveHealth() > 2 || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_NAYRUS_LOVE) || ((logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_LONGSHOT));}}), }); - areaTable[RR_GC_SHOP] = Area("GC Shop", "GC Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GC_SHOP] = Region("GC Shop", "GC Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GC_SHOP_ITEM_1, true), LOCATION(RC_GC_SHOP_ITEM_2, true), @@ -153,89 +152,89 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_GORON_CITY, {[]{return true;}}), }); - areaTable[RR_GC_GROTTO] = Area("GC Grotto", "GC Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GC_GROTTO] = Region("GC Grotto", "GC Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku), - LOCATION(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku), - LOCATION(RC_GC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku), - LOCATION(RC_GC_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_GC_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_GC_GROTTO_PLATFORM, {[]{return true;}}), }); - areaTable[RR_DMC_UPPER_NEARBY] = Area("DMC Upper Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DMC_UPPER_LOCAL, {[]{return logic->FireTimer >= 48;}}), + Entrance(RR_DMC_UPPER_LOCAL, {[]{return logic->FireTimer() >= 48;}}), Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), - Entrance(RR_DMC_UPPER_GROTTO, {[]{return Here(RR_DMC_UPPER_NEARBY, []{return logic->CanBlastOrSmash && (logic->FireTimer >= 8 || logic->Hearts >= 3);});}}) + Entrance(RR_DMC_UPPER_GROTTO, {[]{return Here(RR_DMC_UPPER_NEARBY, []{return logic->BlastOrSmash() && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);});}}) }); - areaTable[RR_DMC_UPPER_LOCAL] = Area("DMC Upper Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DMC_UPPER_LOCAL] = Region("DMC Upper Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives && logic->CanSummonGossipFairyWithoutSuns && (logic->FireTimer >= 16 || logic->Hearts >= 3));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}}), }, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer >= 16 || logic->Hearts >= 3), - LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer >= 8 || logic->Hearts >= 3) && logic->IsChild && logic->CanChildAttack), - LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives && (logic->FireTimer >= 16 || logic->Hearts >= 3)), + LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), + LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()), + LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), }, { //Exits Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}), - Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer >= 16 || logic->Hearts >= 3;}}), - Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), + Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 16 || logic->Hearts() >= 3;}}), + Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}), }); - areaTable[RR_DMC_LADDER_AREA_NEARBY] = Area("DMC Ladder Area Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_LADDER_AREA_NEARBY] = Region("DMC Ladder Region Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DMC_DEKU_SCRUB, logic->IsChild && logic->CanStunDeku), + LOCATION(RC_DMC_DEKU_SCRUB, logic->IsChild && logic->CanStunDeku()), }, { //Exits - Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->Hearts >= 3;}}), - Entrance(RR_DMC_LOWER_NEARBY, {[]{return logic->Hearts >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (randoCtx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (randoCtx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}}), + Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->Hearts() >= 3;}}), + Entrance(RR_DMC_LOWER_NEARBY, {[]{return logic->Hearts() >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (ctx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}}), }); - areaTable[RR_DMC_LOWER_NEARBY] = Area("DMC Lower Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DMC_LOWER_NEARBY] = Region("DMC Lower Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->FireTimer >= 48;}}), + Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->FireTimer() >= 48;}}), Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return true;}}), Entrance(RR_DMC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), Entrance(RR_DMC_HAMMER_GROTTO, {[]{return logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_DMC_LOWER_LOCAL] = Area("DMC Lower Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DMC_LOWER_LOCAL] = Region("DMC Lower Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DMC_LOWER_NEARBY, {[]{return true;}}), - Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer >= 8 || logic->Hearts >= 3;}}), - Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)) && (logic->FireTimer >= 8 || logic->Hearts >= 3);}}), - Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanShield && randoCtx->GetTrickOption(RT_DMC_BOLERO_JUMP))) && logic->FireTimer >= 24;}}), + Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 8 || logic->Hearts() >= 3;}}), + Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanShield() && ctx->GetTrickOption(RT_DMC_BOLERO_JUMP))) && logic->FireTimer() >= 24;}}), }); - areaTable[RR_DMC_CENTRAL_NEARBY] = Area("DMC Central Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_CENTRAL_NEARBY] = Region("DMC Central Nearby", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (randoCtx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->HoverBoots))), - LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer >= 8 || logic->Hearts >= 3)), + LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), }, { //Exits - Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return logic->FireTimer >= 48;}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return logic->FireTimer() >= 48;}}), }); - areaTable[RR_DMC_CENTRAL_LOCAL] = Area("DMC Central Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", "Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DMC_CENTRAL_LOCAL) && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer >= 8 || logic->Hearts >= 3) && logic->CanPlantBugs && logic->CanChildAttack), + LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), }, { //Exits Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return true;}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}), Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}}), - Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return (logic->IsChild && logic->Hearts >= 3 && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer >= 24);}}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}}), }); - areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Area("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { @@ -243,24 +242,24 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), }); - areaTable[RR_DMC_UPPER_GROTTO] = Area("DMC Upper Grotto", "DMC Upper Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", "DMC Upper Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), - LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), }); - areaTable[RR_DMC_HAMMER_GROTTO] = Area("DMC Hammer Grotto", "DMC Hammer Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_HAMMER_GROTTO] = Region("DMC Hammer Grotto", "DMC Hammer Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku), - LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku), - LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku), - LOCATION(RC_DMC_HAMMER_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_DMC_HAMMER_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index d03c9604844..b47ec95a597 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp @@ -4,25 +4,25 @@ using namespace Rando; -void AreaTable_Init_DekuTree() { +void RegionTable_Init_DekuTree() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_DEKU_TREE_ENTRYWAY] = Area("Deku Tree Entryway", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_ENTRYWAY] = Region("Deku Tree Entryway", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DEKU_TREE_LOBBY, {[]{return randoCtx->GetDungeon(DEKU_TREE)->IsVanilla();}}), - Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return randoCtx->GetDungeon(DEKU_TREE)->IsMQ();}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return ctx->GetDungeon(DEKU_TREE)->IsVanilla();}}), + Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return ctx->GetDungeon(DEKU_TREE)->IsMQ();}}), Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(DEKU_TREE)->IsVanilla()) { - areaTable[RR_DEKU_TREE_LOBBY] = Area("Deku Tree Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(DEKU_TREE)->IsVanilla()) { + areaTable[RR_DEKU_TREE_LOBBY] = Region("Deku Tree Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //Locations LOCATION(RC_DEKU_TREE_MAP_CHEST, true), @@ -31,18 +31,18 @@ void AreaTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}), Entrance(RR_DEKU_TREE_COMPASS_ROOM, {[]{return true;}}), - Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);});}}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAttack() || logic->CanUse(RG_NUTS);});}}), Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[RR_DEKU_TREE_2F_MIDDLE_ROOM] = Area("Deku Tree 2F Middle Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_2F_MIDDLE_ROOM] = Region("Deku Tree 2F Middle Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DEKU_TREE_LOBBY, {[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->HasShield || logic->CanUse(RG_MEGATON_HAMMER);});}}), - Entrance(RR_DEKU_TREE_SLINGSHOT_ROOM,{[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->HasShield || logic->CanUse(RG_MEGATON_HAMMER);});}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}}), + Entrance(RR_DEKU_TREE_SLINGSHOT_ROOM,{[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}}), }); - areaTable[RR_DEKU_TREE_SLINGSHOT_ROOM] = Area("Deku Tree Slingshot Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_SLINGSHOT_ROOM] = Region("Deku Tree Slingshot Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, true), LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, true), @@ -51,154 +51,154 @@ void AreaTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}), }); - areaTable[RR_DEKU_TREE_COMPASS_ROOM] = Area("Deku Tree Compass Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DEKU_TREE_COMPASS_ROOM] = Region("Deku Tree Compass Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //Locations LOCATION(RC_DEKU_TREE_COMPASS_CHEST, true), LOCATION(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, true), - LOCATION(RC_DEKU_TREE_GS_COMPASS_ROOM, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_DEKU_TREE_GS_COMPASS_ROOM, logic->CanAttack()), }, { //Exits - Entrance(RR_DEKU_TREE_LOBBY, {[]{return logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW);}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_LOWER] = Area("Deku Tree Basement Lower", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DEKU_TREE_BASEMENT_LOWER] = Region("Deku Tree Basement Lower", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}, + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}, /*Glitched*/[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }, { //Locations LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true), - LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanUseProjectile || logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->CanJumpslash)), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanUseProjectile() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->CanJumpslash())), }, { //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 || randoCtx->GetTrickOption(RT_DEKU_B1_SKIP) || HasAccessTo(RR_DEKU_TREE_BASEMENT_UPPER);}}), + 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_OUTSIDE_BOSS_ROOM, {[]{return false;}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_SCRUB_ROOM] = Area("Deku Tree Basement Scrub Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_BASEMENT_SCRUB_ROOM] = Region("Deku Tree Basement Scrub Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, {[]{return Here(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);});}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT] = Area("Deku Tree Basement Water Room Front", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree Basement Water Room Front", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, {[]{return true;}}), - Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, {[]{return logic->Swim || randoCtx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), + Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, {[]{return logic->HasItem(RG_BRONZE_SCALE) || ctx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK] = Area("Deku Tree Basement Water Room Back", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK] = Region("Deku Tree Basement Water Room Back", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, {[]{return logic->Swim || randoCtx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), + Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, {[]{return logic->HasItem(RG_BRONZE_SCALE) || ctx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_TORCH_ROOM] = Area("Deku Tree Basement Torch Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DEKU_TREE_BASEMENT_TORCH_ROOM] = Region("Deku Tree Basement Torch Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, {[]{return true;}}), - Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return Here(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW);});}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return Here(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_BACK_LOBBY] = Area("Deku Tree Basement Back Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DEKU_TREE_BASEMENT_BACK_LOBBY] = Region("Deku Tree Basement Back Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW);}) && - (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE)));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && + (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE)));}}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), - Entrance(RR_DEKU_TREE_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW);}) && - Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW);}) && logic->IsChild;}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && + Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->IsChild;}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_BACK_ROOM] = Area("Deku Tree Basement Back Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_BASEMENT_BACK_ROOM] = Region("Deku Tree Basement Back Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, logic->HookshotOrBoomerang), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_BASEMENT_UPPER] = Area("Deku Tree Basement Upper", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DEKU_TREE_BASEMENT_UPPER] = Region("Deku Tree Basement Upper", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return logic->IsChild;}}), - Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasFireSourceWithTorch || (randoCtx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), }); - areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Area("Deku Tree Outside Boss Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return true;}}), - Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->Swim || Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->HasShield;});}}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->HasItem(RG_BRONZE_SCALE) || Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(DEKU_TREE)->IsMQ()) { - areaTable[RR_DEKU_TREE_MQ_LOBBY] = Area("Deku Tree MQ Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(DEKU_TREE)->IsMQ()) { + areaTable[RR_DEKU_TREE_MQ_LOBBY] = Region("Deku Tree MQ Lobby", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //Locations LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), - LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanAdultAttack || logic->CanChildAttack), - LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, logic->HasFireSourceWithTorch || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), - LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), - LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanAttack()), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanAttack()), }, { //Exits Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_LOBBY, []{return (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}) && - Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), + Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return Here(RR_DEKU_TREE_MQ_LOBBY, []{return (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}) && - Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch;});}}), - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return randoCtx->GetTrickOption(RT_DEKU_B1_SKIP) || Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->IsAdult;});}}), + Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch();});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->IsAdult;});}}), }); - areaTable[RR_DEKU_TREE_MQ_COMPASS_ROOM] = Area("Deku Tree MQ Compass Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_MQ_COMPASS_ROOM] = Region("Deku Tree MQ Compass Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), - LOCATION(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, logic->HookshotOrBoomerang && + LOCATION(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, logic->HookshotOrBoomerang() && Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) || - (logic->Bombs && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult)) || - (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));})), + (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult)) || + (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));})), }, { //Exits Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Area("Deku Tree MQ Basement Water Room Front", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree MQ Basement Water Room Front", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return randoCtx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && (logic->DekuShield || logic->HylianShield)) || + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && (logic->CanUse(RG_DEKU_SHIELD) || logic->HasItem(RG_HYLIAN_SHIELD))) || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS))));}}), Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK] = Area("Deku Tree MQ Basement Water Room Back", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK] = Region("Deku Tree MQ Basement Water Room Back", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, logic->CanUse(RG_SONG_OF_TIME)), }, { @@ -206,37 +206,37 @@ void AreaTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);});}) && Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || - logic->CanUseProjectile || (logic->CanUse(RG_NUTS) && logic->CanUse(RG_STICKS));});}}), + logic->CanUseProjectile() || (logic->CanUse(RG_NUTS) && logic->CanUse(RG_STICKS));});}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM] = Area("Deku Tree MQ Basement Back Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM] = Region("Deku Tree MQ Basement Back Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_SONG_OF_TIME) && logic->HookshotOrBoomerang)), - LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, logic->HasFireSourceWithTorch && logic->HookshotOrBoomerang), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_SONG_OF_TIME) && logic->HookshotOrBoomerang())), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, logic->HasFireSourceWithTorch() && logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->IsChild;}}), - Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUseProjectile || (logic->CanUse(RG_NUTS) && (logic->IsChild && logic->CanUse(RG_STICKS)));}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUseProjectile() || (logic->CanUse(RG_NUTS) && (logic->IsChild && logic->CanUse(RG_STICKS)));}}), }); - areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Area("Deku Tree MQ Basement Ledge", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Region("Deku Tree MQ Basement Ledge", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku), + LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()), }, { //Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return logic->IsChild;}}), Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, - { [] { return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->HasFireSourceWithTorch; }); } }), + { [] { return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->HasFireSourceWithTorch(); }); } }), }); areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = - Area("Deku Tree MQ Outside Boss Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Deku Tree MQ Outside Boss Room", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{ return true; }}), - Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->Swim || Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->HasShield; }); } }), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->HasItem(RG_BRONZE_SCALE) || Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->CanReflectNuts(); }); } }), }); } @@ -244,22 +244,22 @@ void AreaTable_Init_DekuTree() { | BOSS ROOM | ---------------------------*/ areaTable[RR_DEKU_TREE_BOSS_ENTRYWAY] = - Area("Deku Tree Boss Entryway", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Deku Tree Boss Entryway", "Deku Tree", RA_DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, { [] { return randoCtx->GetDungeon(DEKU_TREE)->IsVanilla(); } }), - Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, { [] { return randoCtx->GetDungeon(DEKU_TREE)->IsMQ(); } }), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, { [] { return ctx->GetDungeon(DEKU_TREE)->IsVanilla(); } }), + Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, { [] { return ctx->GetDungeon(DEKU_TREE)->IsMQ(); } }), Entrance(RR_DEKU_TREE_BOSS_ROOM, { [] { return true; } }), }); areaTable[RR_DEKU_TREE_BOSS_ROOM] = - Area("Deku Tree Boss Room", "Deku Tree", RA_NONE, NO_DAY_NIGHT_CYCLE, + Region("Deku Tree Boss Room", "Deku Tree", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events EventAccess(&logic->DekuTreeClear, { [] { return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) && - (logic->CanJumpslash && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || - logic->HookshotOrBoomerang))); + (logic->CanJumpslash() && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || + logic->HookshotOrBoomerang()))); }}), }, { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp index a1f00e56e94..3826dc7a0af 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp @@ -4,171 +4,172 @@ using namespace Rando; -void AreaTable_Init_DodongosCavern() { +void RegionTable_Init_DodongosCavern() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_DODONGOS_CAVERN_ENTRYWAY] = Area("Dodongos Cavern Entryway", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_ENTRYWAY] = Region("Dodongos Cavern Entryway", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return randoCtx->GetDungeon(DODONGOS_CAVERN)->IsVanilla();}}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, {[]{return randoCtx->GetDungeon(DODONGOS_CAVERN)->IsMQ();}}), + Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla();}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, {[]{return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ();}}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(DODONGOS_CAVERN)->IsVanilla()) { - areaTable[RR_DODONGOS_CAVERN_BEGINNING] = Area("Dodongos Cavern Beginning", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla()) { + areaTable[RR_DODONGOS_CAVERN_BEGINNING] = Region("Dodongos Cavern Beginning", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_BEGINNING, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_BEGINNING, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_LOBBY] = Area("Dodongos Cavern Lobby", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_LOBBY] = Region("Dodongos Cavern Lobby", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->CanSummonGossipFairy && Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBlastOrSmash || logic->GoronBracelet;}));}}), + 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->CanBlastOrSmash || logic->GoronBracelet;})), - LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku || logic->GoronBracelet), - LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBlastOrSmash || logic->GoronBracelet;})), + LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return 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, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, { //Exits 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->CanBlastOrSmash || logic->GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, {[]{return Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->BlastOrSmash() || 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_BOSS_AREA, {[]{return Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HasExplosives();});}}), Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY,{[]{return false;}}), }); - areaTable[RR_DODONGOS_CAVERN_LOBBY_SWITCH] = Area("Dodongos Cavern Lobby Switch", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_LOBBY_SWITCH] = Region("Dodongos Cavern Lobby Switch", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_SE_CORRIDOR] = Area("Dodongos Cavern SE Corridor", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_SE_CORRIDOR] = Region("Dodongos Cavern SE Corridor", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (randoCtx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAdultAttack || logic->CanChildAttack))), + LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_SE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return logic->CanBlastOrSmash || logic->CanAdultAttack || logic->CanChildAttack || (logic->CanTakeDamage && logic->CanShield);});}}), + //Shield in logic to block baby dodongos to make them blow up the wall? + Entrance(RR_DODONGOS_CAVERN_SE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return logic->BlastOrSmash() || logic->CanAttack() || (logic->TakeDamage() && logic->CanShield());});}}), Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_SE_ROOM] = Area("Dodongos Cavern SE Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_SE_ROOM] = Region("Dodongos Cavern SE Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, logic->CanAttack()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS] = Area("Dodongos Cavern Near Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS] = Region("Dodongos Cavern Near Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Area("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || - logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives;});}}), + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || - logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives;});}}), + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Area("Dodongos Cavern Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Region("Dodongos Cavern Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, {[]{return logic->HasFireSourceWithTorch;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, {[]{return logic->HasFireSourceWithTorch();}}), Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_NEAR_DODONGO_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_NEAR_DODONGO_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_NEAR_DODONGO_ROOM] = Area("Dodongos Cavern Near Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_NEAR_DODONGO_ROOM] = Region("Dodongos Cavern Near Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, logic->CanStunDeku), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, logic->CanStunDeku()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_STAIRS_LOWER] = Area("Dodongos Cavern Stairs Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_STAIRS_LOWER] = Region("Dodongos Cavern Stairs Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, {[]{return logic->HasExplosives || logic->GoronBracelet || logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}), - Entrance(RR_DODONGOS_CAVERN_COMPASS_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, {[]{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_DODONGOS_CAVERN_COMPASS_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Area("Dodongos Cavern Stairs Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Region("Dodongos Cavern Stairs Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //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->CanChildAttack || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && randoCtx->GetTrickOption(RT_DC_VINES_GS))), + 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))), }, { //Exits Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_COMPASS_ROOM] = Area("Dodongos Cavern Compass Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_COMPASS_ROOM] = Region("Dodongos Cavern Compass Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, true), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->GoronBracelet;}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET);}}), }); - areaTable[RR_DODONGOS_CAVERN_ARMOS_ROOM] = Area("Dodongos Cavern Armos Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_ARMOS_ROOM] = Region("Dodongos Cavern Armos Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Area("Dodongos Cavern Bomb Room Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Region("Dodongos Cavern Bomb Room Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, true), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBlastOrSmash || (randoCtx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->GoronBracelet);});}}), - Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), - Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return (logic->IsAdult && randoCtx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->BlastOrSmash() || (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->BlastOrSmash() || 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));}}), }); - areaTable[RR_DODONGOS_CAVERN_2F_SIDE_ROOM] = Area("Dodongos Cavern 2F Side Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_2F_SIDE_ROOM] = Region("Dodongos Cavern 2F Side Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, logic->CanStunDeku), - LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, logic->CanStunDeku), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, logic->CanStunDeku()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM] = Area("Dodongos Cavern First Slingshot Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM] = Region("Dodongos Cavern First Slingshot Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //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) || randoCtx->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);}}), }); - areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Area("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //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->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || - logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives;});}}), + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || - logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives;});}}), + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Area("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Region("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || randoCtx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), }); - areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Area("Dodongos Cavern Bomb Room Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Region("Dodongos Cavern Bomb Room Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, true), }, { @@ -178,28 +179,28 @@ void AreaTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_FAR_BRIDGE] = Area("Dodongos Cavern Far Bridge", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_FAR_BRIDGE] = Region("Dodongos Cavern Far Bridge", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->CanBlastOrSmash;})), + LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->BlastOrSmash();})), }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_BOSS_AREA] = Area("Dodongos Cavern Boss Area", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_BOSS_AREA] = Region("Dodongos Cavern Boss Region", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->CanBlastOrSmash;});}}), + Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->BlastOrSmash();});}}), Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_BACK_ROOM] = Area("Dodongos Cavern Back Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_BACK_ROOM] = Region("Dodongos Cavern Back Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_BACK_ROOM, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_DODONGOS_CAVERN_GS_BACK_ROOM, logic->CanAttack()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}), @@ -209,159 +210,252 @@ void AreaTable_Init_DodongosCavern() { /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(DODONGOS_CAVERN)->IsMQ()) { - areaTable[RR_DODONGOS_CAVERN_MQ_BEGINNING] = Area("Dodongos Cavern MQ Beginning", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ()) { + areaTable[RR_DODONGOS_CAVERN_MQ_BEGINNING] = Region("Dodongos Cavern MQ Beginning", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Area("Dodongos Cavern MQ Lobby", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return (logic->CanBlastOrSmash || logic->GoronBracelet) && logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->CanUse(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBlastOrSmash || logic->GoronBracelet), - LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku), - LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku), - LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBlastOrSmash || logic->GoronBracelet;})), + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET);})), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_ELEVATOR, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return logic->IsAdult;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(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))));});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_ELEVATOR] = Area("Dodongos Cavern MQ Elevator", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), + EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}}), + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->ClearMQDCUpperLobbyRocks;}}), + //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->CanJumpslash() && 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 + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER] = Region("Dodongos Cavern MQ Stairs Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + //Events + //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->HasExplosives || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}), + }, {}, { + //Exits + //This is possible with sticks and shield, igniting a first flower by "touch" then very quickly crouch stabbing in a way that cuts the corner to light the 3rd bomb on the other side, but that's a trick + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || + (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->CanBreakMudWalls();});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL] = Region("Dodongos Cavern MQ Stairs Past Mud Wall", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), + //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->CanUse(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku), - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanChildAttack || logic->CanAdultAttack)), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_ABOVE_STAIRCASE, {[]{return logic->CanChildAttack || logic->CanAdultAttack || logic->CanUse(RG_NUTS);}}), - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_ELEVATOR, []{return logic->CanBlastOrSmash || logic->CanUse(RG_DINS_FIRE);});}}), - Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return randoCtx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS)) && logic->CanTakeDamage;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH, {[]{return logic->HasExplosives;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->CanUse(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_ABOVE_STAIRCASE] = Area("Dodongos Cavern MQ Above Staircase", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER] = Region("Dodongos Cavern MQ Stairs Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku()), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS);}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Area("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS] = Region("Dodongos Cavern MQ Past Big Skulltulas", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS);}}), + 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;*/ + Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}),//if we add BONKO or other crate logic, logic for silver rupees goes here + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM] = Region("Dodongos Cavern MQ Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_ABOVE_STAIRCASE, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM, {[]{return logic->HasFireSourceWithTorch;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_UPPER_LIZALFOS, {[]{return logic->HasFireSourceWithTorch;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + //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);}}), + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->TakeDamage();}}), + 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);}}), + 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 + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), + Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return (logic->HasFireSource() && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanBreakMudWalls();}}), //Requires stregnth 0, If you can somehow warp into this room, add logic->CanPassEnemy(RE_BIG_SKULLTULA) }); - areaTable[RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM] = Area("Dodongos Cavern MQ Larvae Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM] = Region("Dodongos Cavern MQ Larvae Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, true), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, true), //implied logic->CanKillEnemy(RE_GOLD_SKULTULLA) based on entry reqs. Add crate logic when BONKO is added }, { //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts }); - areaTable[RR_DODONGOS_CAVERN_MQ_BEFORE_UPPER_LIZALFOS] = Area("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA) }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->CanUse(RG_STICKS);}}), + //Falling down gets you stuck with nothing there, not a useful exit for logic + Entrance(RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Area("Dodongos Cavern MQ Torch Puzzle Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->IsAdult || (Here(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, []{return logic->BlastOrSmash() || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}));}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Region("Dodongos Cavern MQ Torch Puzzle Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}}), + }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, (logic->CanAdultAttack || logic->CanChildAttack) && logic->CanBlastOrSmash), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_UPPER_LIZALFOS, {[]{return logic->IsAdult || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->Bombs || logic->CanUse(RG_KOKIRI_SWORD);}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return logic->GoronBracelet && logic->CanTakeDamage;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return logic->HasExplosives;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH, {[]{return logic->GoronBracelet && (logic->IsAdult && randoCtx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && randoCtx->GetTrickOption(RT_DC_MQ_CHILD_EYES));}}), + Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return logic->ClearMQDCUpperLobbyRocks;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Area("Dodongos Cavern MQ Lower Right Side", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Region("Dodongos Cavern MQ Lower Right Side", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, (logic->CanBlastOrSmash || logic->GoronBracelet) && logic->CanStunDeku), + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanStunDeku()), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->CanUse(RG_FAIRY_BOW);}) || logic->GoronBracelet || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives) && logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanHitEyeTargets();}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Area("Dodongos Cavern MQ Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Region("Dodongos Cavern MQ Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + //When you add wonder item logic for behind the lavafall, use Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS) to account for jumping down instead of an exit + //because the doors are sealed when entering from the top and you can't spawn the lower lizalfos + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_POES_ROOM] = Region("Dodongos Cavern MQ Poes Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), //If you can get to the locked part of POES_ROOM without a way to open it or passing the chest, this will need it's own room + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && //could be a seperate room if it gets busy + logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT, 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))) }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->IsAdult;});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_POES_ROOM] = Area("Dodongos Cavern MQ Poes Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM] = Region("Dodongos Cavern Mad Scrub Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanUse(RG_FAIRY_BOW);}) || logic->GoronBracelet || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives) && logic->HookshotOrBoomerang), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT, 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))) }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Region("Dodongos Cavern MQ Behind Mouth", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), + //using pots to get past the fire is in default logic. if stregnth 0 gets added, this will need to be: + //stregnth 0 || explosives, or projectiles if str0 isn't needed to pull graves (it's a narrow shot though, may be trick worthy) + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, {[]{return logic->IsAdult;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH] = Area("Dodongos Cavern MQ Mouth", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Region("Dodongos Cavern MQ Back Behind Fire", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanAdultAttack || logic->CanUse(RG_BOOMERANG) || ((logic->HasExplosives || logic->CanUse(RG_DINS_FIRE)) && logic->CanChildAttack || logic->GoronBracelet)), + LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, {[]{return logic->IsAdult || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE) || - (randoCtx->GetTrickOption(RT_DC_MQ_CHILD_EYES) && (logic->CanUse(RG_STICKS) || (logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))));}}), + 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();});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS] = Area("Dodongos Cavern MQ Before Boss", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE] = Region("Dodongos Cavern MQ BossArea", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events 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_RANG_OR_HOOKSHOT)) || + (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/);})), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), //if strength 0 prevents grave pulls, add it here }); + } /*--------------------------- | BOSS ROOM | ---------------------------*/ areaTable[RR_DODONGOS_CAVERN_BOSS_ENTRYWAY] = - Area("Dodongos Cavern Boss Entryway", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Dodongos Cavern Boss Entryway", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, { [] { return randoCtx->GetDungeon(DODONGOS_CAVERN)->IsVanilla(); } }), - Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, { [] { return randoCtx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla(); } }), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }), Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }), }); areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = - Area("Dodongos Cavern Boss Room", "Dodongos Cavern", RA_NONE, NO_DAY_NIGHT_CYCLE, + Region("Dodongos Cavern Boss Room", "Dodongos Cavern", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events EventAccess(&logic->DodongosCavernClear, { [] { return logic->DodongosCavernClear || (logic->HasBossSoul(RG_KING_DODONGO_SOUL) && (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, - [] { return logic->HasExplosives || (logic->CanUse(RG_MEGATON_HAMMER) && randoCtx->GetTrickOption(RT_DC_HAMMER_FLOOR)); }) && - (logic->Bombs || logic->GoronBracelet) && logic->CanJumpslash)); /*todo add chu kill to tricks*/ + [] { return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR)); }) && + (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanJumpslash())); /*todo add chu kill to tricks*/ }}), }, { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp index b3c2e5387d1..1984552b5b4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp @@ -4,32 +4,32 @@ using namespace Rando; -void AreaTable_Init_FireTemple() { +void RegionTable_Init_FireTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_FIRE_TEMPLE_ENTRYWAY] = Area("Fire Temple Entryway", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_ENTRYWAY] = Region("Fire Temple Entryway", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return randoCtx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}}), - Entrance(RR_FIRE_TEMPLE_MQ_LOWER, {[]{return randoCtx->GetDungeon(FIRE_TEMPLE)->IsMQ();}}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}}), Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(FIRE_TEMPLE)->IsVanilla()) { - areaTable[RR_FIRE_TEMPLE_FIRST_ROOM] = Area("Fire Temple First Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla()) { + areaTable[RR_FIRE_TEMPLE_FIRST_ROOM] = Region("Fire Temple First Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { }, { //Exits Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return logic->FireTimer >= 24;}}), + 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->IsKeysanity);}}), 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(RR_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}}), }); - areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Area("Fire Temple Near Boss Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), }, { @@ -38,35 +38,35 @@ void AreaTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyFireTemple && ((logic->IsAdult && (randoCtx->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->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((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));}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Area("Fire Temple Loop Enemies", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity;}}), Entrance(RR_FIRE_TEMPLE_LOOP_TILES, {[]{return Here(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER);});}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_TILES] = Area("Fire Temple Loop Tiles", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_TILES] = Region("Fire Temple Loop Tiles", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, logic->CanAttack()), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Area("Fire Temple Loop Flare Dancer", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Region("Fire Temple Loop Flare Dancer", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //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), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_TILES, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Area("Fire Temple Loop Hammer Switch", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FireLoopSwitch, {[]{return logic->FireLoopSwitch || logic->CanUse(RG_MEGATON_HAMMER);}}), }, {}, { @@ -75,7 +75,7 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_GORON_ROOM] = Area("Fire Temple Loop Goron Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_GORON_ROOM] = Region("Fire Temple Loop Goron Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, true), }, { @@ -84,22 +84,22 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_EXIT] = Area("Fire Temple Loop Exit", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_EXIT] = Region("Fire Temple Loop Exit", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Area("Fire Temple Big Lava Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Region("Fire Temple Big Lava Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return logic->SmallKeys(RR_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) || randoCtx->GetTrickOption(RT_FIRE_SOT));}}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, {[]{return logic->IsAdult && logic->HasExplosives;}}), + 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);}}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Area("Fire Temple Big Lava Room North Goron", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Region("Fire Temple Big Lava Room North Goron", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, true), }, { @@ -107,15 +107,16 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES] = Area("Fire Temple Big Lava Room North Tiles", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES] = Region("Fire Temple Big Lava Room North Tiles", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, logic->CanAdultAttack || logic->HookshotOrBoomerang), + //RANDOTODO check if child can reach + LOCATION(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, (logic->IsAdult && logic->CanAttack()) || logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON] = Area("Fire Temple Big Lava Room South Goron", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON] = Region("Fire Temple Big Lava Room South Goron", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, true), }, { @@ -123,32 +124,32 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Area("Fire Temple Fire Pillar Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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_SHORTCUT_ROOM, {[]{return logic->FireTimer() >= 56 && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}}), }); - areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Area("Fire Temple Shortcut Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //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(RR_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->GoronBracelet || randoCtx->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->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}}), }); - areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Area("Fire Temple Shortcut Climb", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Area("Fire Temple Boulder Maze Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives && (logic->IsAdult || logic->HookshotOrBoomerang)), + LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), @@ -157,7 +158,7 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return false;}}), }); - areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM] = Area("Fire Temple Boulder Maze Lower Side Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM] = Region("Fire Temple Boulder Maze Lower Side Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, true), }, { @@ -165,23 +166,23 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Area("Fire Temple East Central Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->CanTakeDamage;}}), + 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_MAP_AREA, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Area("Fire Temple Fire Wall Chase", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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(RR_FIRE_TEMPLE, 6, 8);}}), 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_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);}}), }); - areaTable[RR_FIRE_TEMPLE_MAP_AREA] = Area("Fire Temple Map Area", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_MAP_AREA] = Region("Fire Temple Map Region", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, true), }, { @@ -189,59 +190,59 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Area("Fire Temple Boulder Maze Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Region("Fire Temple Boulder Maze Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return logic->HasExplosives;}}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return logic->HasExplosives();}}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return logic->CanUse(RG_SCARECROW) || (randoCtx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return logic->CanUse(RG_SCARECROW) || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}}), }); - areaTable[RR_FIRE_TEMPLE_SCARECROW_ROOM] = Area("Fire Temple Scarecrow Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_SCARECROW_ROOM] = Region("Fire Temple Scarecrow Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), }, { //Exits Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_EAST_PEAK, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_EAST_PEAK] = Area("Fire Temple East Peak", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_EAST_PEAK] = Region("Fire Temple East Peak", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanUseProjectile), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanUseProjectile()), }, { //Exits Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->CanTakeDamage;}}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->TakeDamage();}}), }); - areaTable[RR_FIRE_TEMPLE_CORRIDOR] = Area("Fire Temple Corridor", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_CORRIDOR] = Region("Fire Temple Corridor", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 7);}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Area("Fire Temple Fire Maze Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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_SIDE_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 8);}}), - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return randoCtx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}}), + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return ctx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Area("Fire Temple Fire Maze Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Region("Fire Temple Fire Maze Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM] = Area("Fire Temple Fire Maze Side Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM] = Region("Fire Temple Fire Maze Side Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, true), }, { @@ -249,9 +250,9 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Area("Fire Temple West Central Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Region("Fire Temple West Central Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, Here(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER);})), + 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);}}), @@ -259,50 +260,50 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Area("Fire Temple West Central Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Region("Fire Temple West Central Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Area("Fire Temple Late Fire Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Region("Fire Temple Late Fire Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return false;}}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return logic->HasExplosives;}}), + Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return logic->HasExplosives();}}), }); - areaTable[RR_FIRE_TEMPLE_UPPER_FLARE_DANCER] = Area("Fire Temple Upper Flare Dancer", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_UPPER_FLARE_DANCER] = Region("Fire Temple Upper Flare Dancer", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), - Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)));});}}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CLIMB] = Area("Fire Temple West Climb", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_WEST_CLIMB] = Region("Fire Temple West Climb", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_WEST_PEAK, {[]{return logic->CanUseProjectile;}}), + Entrance(RR_FIRE_TEMPLE_WEST_PEAK, {[]{return logic->CanUseProjectile();}}), }); - areaTable[RR_FIRE_TEMPLE_WEST_PEAK] = Area("Fire Temple West Peak", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_WEST_PEAK] = Region("Fire Temple West Peak", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return logic->CanTakeDamage;}}), + Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return logic->TakeDamage();}}), Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_FIRE_TEMPLE_HAMMER_RETURN_PATH] = Area("Fire Temple Hammer Return Path", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_HAMMER_RETURN_PATH] = Region("Fire Temple Hammer Return Path", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE] = Area("Fire Temple Above Fire Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE] = Region("Fire Temple Above Fire Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), @@ -312,81 +313,81 @@ void AreaTable_Init_FireTemple() { /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(FIRE_TEMPLE)->IsMQ()) { - areaTable[RR_FIRE_TEMPLE_MQ_LOWER] = Area("Fire Temple MQ Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FIRE_TEMPLE)->IsMQ()) { + areaTable[RR_FIRE_TEMPLE_MQ_LOWER] = Region("Fire Temple MQ Lower", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->Bombs || logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->IsAdult && (randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (randoCtx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO) && randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_QUADRUPLE) && randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OCTUPLE) && randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)))))), - //Trick: logic->IsAdult && (LogicFewerTunicRequirements || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (LogicFireMQNearBoss && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT))))) + LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->IsAdult && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_QUADRUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OCTUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)))))), + //Trick: logic->IsAdult && (LogicFewerTunicRequirements || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (LogicFireMQNearBoss && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT))))) }, { //Exits Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_MEGATON_HAMMER) && logic->BossKeyFireTemple && ((logic->HasFireSource && (randoCtx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->HoverBoots)) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER));}}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((logic->HasFireSource() && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER));}}), Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return logic->IsAdult && logic->FireTimer >= 24 && logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return logic->IsAdult && logic->FireTimer() >= 24 && logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR] = Area("Fire Temple MQ Lower Locked Door", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR] = Region("Fire Temple MQ Lower Locked Door", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG))))), + LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG))))), LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, {}); - areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Area("Fire Temple MQ Big Lava Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->HasFireSource && (logic->Bow || randoCtx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || randoCtx->GetTrickOption(RT_FIRE_SOT)));}}), - //Trick: logic->HasFireSource && (logic->Bow || LogicFireMQBKChest) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireSongOfTime) + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_SOT)));}}), + //Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireSongOfTime) }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasFireSource && (logic->Bow || randoCtx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), - //Trick: logic->HasFireSource && (logic->Bow || LogicFireMQBKChest) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT) - LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource && logic->HasExplosives && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || randoCtx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))), - //Trick: logic->HasFireSource && logic->HasExplosives && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireMQBlockedChest) + LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), + //Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT) + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))), + //Trick: logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireMQBlockedChest) LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource || (randoCtx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->HoverBoots));}}), - //Trick: logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource || (LogicFireMQClimb && logic->HoverBoots)) + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (LogicFireMQClimb && logic->CanUse(RG_HOVER_BOOTS))) }); - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Area("Fire Temple MQ Lower Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives && (randoCtx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER_MAZE))), - //Trick: logic->HasExplosives && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult()) + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER_MAZE))), + //Trick: logic->HasExplosives() && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult()) }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return (logic->IsAdult && ((logic->HasExplosives && logic->CanUse(RG_HOOKSHOT)) || (randoCtx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)))) || randoCtx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP);}}), - //Trick: (logic->IsAdult && ((logic->HasExplosives && logic->CanUse(RG_HOOKSHOT)) || (LogicFireMQMazeHovers && logic->CanUse(RG_HOVER_BOOTS)))) || LogicFireMQMazeJump + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)))) || ctx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP);}}), + //Trick: (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (LogicFireMQMazeHovers && logic->CanUse(RG_HOVER_BOOTS)))) || LogicFireMQMazeJump }); - areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE] = Area("Fire Temple MQ Upper Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE] = Region("Fire Temple MQ Upper Maze", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && (((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives) || logic->CanUse(RG_LONGSHOT))));}}), + //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && (((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))));}}), EventAccess(&logic->FairyPot, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasExplosives), - LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives) || logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_UPPER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3) && logic->IsAdult && ((logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_FIRE_ARROWS));}}), }); - areaTable[RR_FIRE_TEMPLE_MQ_UPPER] = Area("Fire Temple MQ Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_UPPER] = Region("Fire Temple MQ Upper", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)) && logic->CanUse(RG_HOOKSHOT)) || randoCtx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), + LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)) && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), //Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze - LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || randoCtx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)) && logic->SmallKeys(RR_FIRE_TEMPLE, 4)), + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)) && logic->SmallKeys(RR_FIRE_TEMPLE, 4)), //Trick: ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze) && logic->SmallKeys(RR_FIRE_TEMPLE, 4) - LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanUse(RG_SONG_OF_TIME) || logic->HoverBoots || randoCtx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), - //Trick: logic->CanUse(RG_SONG_OF_TIME) || logic->HoverBoots || LogicFireMQFlameMaze - LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives), - LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (randoCtx->GetTrickOption(RT_FIRE_MQ_ABOVE_MAZE_GS) && logic->IsAdult && logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || LogicFireMQFlameMaze + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (ctx->GetTrickOption(RT_FIRE_MQ_ABOVE_MAZE_GS) && logic->IsAdult && logic->CanUse(RG_LONGSHOT))), //Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && logic->IsAdult && logic->CanUse(RG_LONGSHOT)) }, {}); } @@ -395,20 +396,20 @@ void AreaTable_Init_FireTemple() { | BOSS ROOM | ---------------------------*/ areaTable[RR_FIRE_TEMPLE_BOSS_ENTRYWAY] = - Area("Fire Temple Boss Entryway", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Fire Temple Boss Entryway", "Fire Temple", RA_FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return randoCtx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false; } }), - Entrance(RR_FIRE_TEMPLE_MQ_LOWER, { [] { return randoCtx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false; } }), Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = - Area("Fire Temple Boss Room", "Fire Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, + Region("Fire Temple Boss Room", "Fire Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events EventAccess(&logic->FireTempleClear, - { [] { return logic->FireTempleClear || (logic->HasBossSoul(RG_VOLVAGIA_SOUL) && (logic->FireTimer >= 64 && logic->CanUse(RG_MEGATON_HAMMER))); }}), + { [] { return logic->FireTempleClear || (logic->HasBossSoul(RG_VOLVAGIA_SOUL) && (logic->FireTimer() >= 64 && logic->CanUse(RG_MEGATON_HAMMER))); }}), }, { // Locations diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp index eaaee1f36e0..56b0499cc46 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp @@ -4,43 +4,43 @@ using namespace Rando; -void AreaTable_Init_ForestTemple() { +void RegionTable_Init_ForestTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_FOREST_TEMPLE_ENTRYWAY] = Area("Forest Temple Entryway", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_ENTRYWAY] = Region("Forest Temple Entryway", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return randoCtx->GetDungeon(FOREST_TEMPLE)->IsVanilla();}}), - Entrance(RR_FOREST_TEMPLE_MQ_LOBBY, {[]{return randoCtx->GetDungeon(FOREST_TEMPLE)->IsMQ();}}), + Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla();}}), + Entrance(RR_FOREST_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(FOREST_TEMPLE)->IsMQ();}}), Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(FOREST_TEMPLE)->IsVanilla()) { - areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Area("Forest Temple First Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla()) { + areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Region("Forest Temple First Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true), - LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->Bombs) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslash || (logic->IsChild && logic->Bombs)))), + LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslash() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG))))), }, { //Exits Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_SOUTH_CORRIDOR] = Area("Forest Temple South Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_SOUTH_CORRIDOR] = Region("Forest Temple South Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[RR_FOREST_TEMPLE_LOBBY] = Area("Forest Temple Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_LOBBY] = Region("Forest Temple Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleMeg, {[]{return logic->ForestTempleMeg || (logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW));}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang), + LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), @@ -53,13 +53,13 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[RR_FOREST_TEMPLE_NORTH_CORRIDOR] = Area("Forest Temple North Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_NORTH_CORRIDOR] = Region("Forest Temple North Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_LOWER_STALFOS, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_LOWER_STALFOS] = Area("Forest Temple Lower Stalfos", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_LOWER_STALFOS] = Region("Forest Temple Lower Stalfos", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { @@ -70,26 +70,26 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER] = Area("Forest Temple NW Outdoors Lower", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER] = Region("Forest Temple NW Outdoors Lower", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //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) || Here(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HookshotOrBoomerang();})), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return false;}}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_SEWER, {[]{return logic->GoldScale || 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) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER] = Area("Forest Temple NW Outdoors Upper", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER] = Region("Forest Temple NW Outdoors Upper", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), @@ -98,43 +98,43 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER] = Area("Forest Temple NE Outdoors Lower", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER] = Region("Forest Temple NE Outdoors Lower", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //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 && randoCtx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->HoverBoots)), - LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (randoCtx->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) || 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();})), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT));}}), - Entrance(RR_FOREST_TEMPLE_SEWER, {[]{return logic->GoldScale || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), + 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_FALLING_ROOM, {[]{return false;}}), }); - areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER] = Area("Forest Temple NE Outdoors Upper", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER] = Region("Forest Temple NE Outdoors Upper", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return randoCtx->GetTrickOption(RT_FOREST_DOORFRAME) && logic->CanJumpslash && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_SCARECROW);}}), + Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return ctx->GetTrickOption(RT_FOREST_DOORFRAME) && logic->CanJumpslash() && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_SCARECROW);}}), }); - areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Area("Forest Temple Map Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Region("Forest Temple Map Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));})), + LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanShield()));})), }, { //Exits - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}), - Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanShield()));});}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanShield()));});}}), }); - areaTable[RR_FOREST_TEMPLE_SEWER] = Area("Forest Temple Sewer", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), }, { @@ -143,43 +143,43 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Area("Forest Temple Below Boss Key Chest", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Region("Forest Temple Below Boss Key Chest", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return logic->HasExplosives || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanShield));});}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT)) && (logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanShield()));});}}), }); - areaTable[RR_FOREST_TEMPLE_FLOORMASTER_ROOM] = Area("Forest Temple Floormaster Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_FLOORMASTER_ROOM] = Region("Forest Temple Floormaster Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, logic->CanAdultDamage || logic->CanChildDamage), + LOCATION(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, logic->CanDamage()), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_WEST_CORRIDOR] = Area("Forest Temple West Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_WEST_CORRIDOR] = Region("Forest Temple West Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}}), - Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Area("Forest Temple Block Push Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Region("Forest Temple Block Push Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->GoronBracelet && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), }, { //Exits Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS) || (randoCtx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslash && logic->GoronBracelet);}}), - Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return logic->IsAdult && logic->GoronBracelet && 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->GoronBracelet && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslash() && 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);}}), }); - areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Area("Forest Temple NW Corridor Twisted", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Region("Forest Temple NW Corridor Twisted", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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);}}), }); - areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED] = Area("Forest Temple NW Corridor Straightened", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED] = Region("Forest Temple NW Corridor Straightened", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, true), }, { @@ -188,7 +188,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), }); - areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Area("Forest Temple Red Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleJoelle, {[]{return logic->ForestTempleJoelle || logic->CanUse(RG_FAIRY_BOW);}}), }, { @@ -200,7 +200,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_UPPER_STALFOS] = Area("Forest Temple Upper Stalfos", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_UPPER_STALFOS] = Region("Forest Temple Upper Stalfos", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), }, { @@ -209,7 +209,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_BLUE_POE_ROOM, {[]{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[RR_FOREST_TEMPLE_BLUE_POE_ROOM] = Area("Forest Temple Blue Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_BLUE_POE_ROOM] = Region("Forest Temple Blue Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleBeth, {[]{return logic->ForestTempleBeth || logic->CanUse(RG_FAIRY_BOW);}}), }, { @@ -221,25 +221,25 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}}), }); - areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED] = Area("Forest Temple NE Corridor Straightened", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED] = Region("Forest Temple NE Corridor Straightened", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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);}}), }); - areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED] = Area("Forest Temple NE Corridor Twisted", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED] = Region("Forest Temple NE Corridor Twisted", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}}), Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_FROZEN_EYE_ROOM] = Area("Forest Temple Frozen Eye Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_FROZEN_EYE_ROOM] = Region("Forest Temple Frozen Eye Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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));}}), }); - areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Area("Forest Temple Falling Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Region("Forest Temple Falling Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), }, { @@ -248,7 +248,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Area("Forest Temple Green Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Region("Forest Temple Green Poe Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleAmy, {[]{return logic->ForestTempleAmy || logic->CanUse(RG_FAIRY_BOW);}}), }, {}, { @@ -257,92 +257,92 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, {[]{return logic->ForestTempleAmy;}}), }); - areaTable[RR_FOREST_TEMPLE_EAST_CORRIDOR] = Area("Forest Temple East Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_EAST_CORRIDOR] = Region("Forest Temple East Corridor", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}), - Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS);}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), + Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[RR_FOREST_TEMPLE_BOSS_REGION] = Area("Forest Temple Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_BOSS_REGION] = Region("Forest Temple Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_BASEMENT_CHEST, true), - LOCATION(RC_FOREST_TEMPLE_GS_BASEMENT, logic->HookshotOrBoomerang), + LOCATION(RC_FOREST_TEMPLE_GS_BASEMENT, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyForestTemple;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(FOREST_TEMPLE)->IsMQ()) { - areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Area("Forest Temple MQ Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FOREST_TEMPLE)->IsMQ()) { + areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Region("Forest Temple MQ Lobby", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanJumpslash || logic->Bombs || logic->CanUse(RG_STICKS) || logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang || logic->CanUse(RG_DINS_FIRE) || logic->KokiriSword || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanJumpslash() || logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAdultAttack || logic->CanChildAttack || logic->CanUse(RG_NUTS));}}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAttack() || logic->CanUse(RG_NUTS));}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Area("Forest Temple MQ Central Area", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Region("Forest Temple MQ Central Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild) && (logic->CanJumpslash || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->KokiriSword)), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild) && (logic->CanJumpslash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_KOKIRI_SWORD))), LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), //This is as far as child can get - Entrance(RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return logic->IsAdult && (logic->GoronBracelet || (randoCtx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)));}}), - //Trick: logic->IsAdult && (logic->GoronBracelet || (LogicForestMQBlockPuzzle && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))) - Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (randoCtx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (randoCtx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)));}}), + //Trick: logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (LogicForestMQBlockPuzzle && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))) + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), //Trick (logic->Hookshot trick not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp): (LogicForestMQHallwaySwitchJS && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (LogicForestMQHallwaySwitchHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestTempleJoAndBeth && logic->ForestTempleAmyAndMeg;}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE] = Area("Forest Temple MQ After Block Puzzle", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE] = Region("Forest Temple MQ After Block Puzzle", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_FOREST_TEMPLE, 3)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_BOW_REGION, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}}), - Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 3) || (randoCtx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || (randoCtx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->IsAdult || (logic->IsChild && logic->CanUse(RG_STICKS))))));}}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 3) || (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->IsAdult || (logic->IsChild && logic->CanUse(RG_STICKS))))));}}), //Trick (Doing the hallway switch jumpslash as child requires sticks and has been added above): logic->SmallKeys(RR_FOREST_TEMPLE, 3) || (LogicForestMQHallwaySwitchJS && ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicForestOutsideBackdoor)) Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE] = Area("Forest Temple MQ Outdoor Ledge", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE] = Region("Forest Temple MQ Outdoor Ledge", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanJumpslash), + LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanJumpslash()), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_NW_OUTDOORS] = Area("Forest Temple MQ NW Outdoors", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_NW_OUTDOORS] = Region("Forest Temple MQ NW Outdoors", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanAttack()), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (logic->IsAdult && (logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT)))) || logic->ProgressiveScale >= 2;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (logic->IsAdult && (logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT)))) || logic->HasItem(RG_GOLDEN_SCALE);}}), //Trick: (logic->IsAdult && (logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (LogicForestMQWellSwim && logic->CanUse(RG_HOOKSHOT)))) || logic->ProgressiveScale >= 2 Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS] = Area("Forest Temple MQ NE Outdoors", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS] = Region("Forest Temple MQ NE Outdoors", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE));}}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), - LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->HookshotOrBoomerang || (logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_HOVER_BOOTS) && randoCtx->GetTrickOption(RT_FOREST_DOORFRAME))))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->HookshotOrBoomerang() || (logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))))), LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, (logic->IsAdult && ((logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), }, { //Exits @@ -350,17 +350,17 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES] = Area("Forest Temple MQ Outdoors Top Ledges", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES] = Region("Forest Temple MQ Outdoors Top Ledges", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return true;}}), - Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return randoCtx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}}), //Trick: LogicForestOutdoorsLedge && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) }); - areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE] = Area("Forest Temple MQ NE Outdoors Ledge", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE] = Region("Forest Temple MQ NE Outdoors Ledge", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, true), }, { @@ -369,7 +369,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_BOW_REGION] = Area("Forest Temple MQ Bow Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_MQ_BOW_REGION] = Region("Forest Temple MQ Bow Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleJoAndBeth, {[]{return logic->ForestTempleJoAndBeth || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), }, { @@ -382,7 +382,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 5) && ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE));}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_FALLING_ROOM] = Area("Forest Temple MQ Falling Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_FOREST_TEMPLE_MQ_FALLING_ROOM] = Region("Forest Temple MQ Falling Room", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleAmyAndMeg, {[]{return logic->ForestTempleAmyAndMeg || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && logic->SmallKeys(RR_FOREST_TEMPLE, 6));}}), }, { @@ -393,12 +393,12 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_MQ_BOSS_REGION] = Area("Forest Temple MQ Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FOREST_TEMPLE_MQ_BOSS_REGION] = Region("Forest Temple MQ Boss Region", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, true), }, { //Exits - Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyForestTemple;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}}), }); } @@ -406,15 +406,15 @@ void AreaTable_Init_ForestTemple() { | BOSS ROOM | ---------------------------*/ areaTable[RR_FOREST_TEMPLE_BOSS_ENTRYWAY] = - Area("Forest Temple Boss Entryway", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Forest Temple Boss Entryway", "Forest Temple", RA_FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_FOREST_TEMPLE_BOSS_REGION, { [] { return randoCtx->GetDungeon(FOREST_TEMPLE)->IsVanilla() && false; } }), - Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, { [] { return randoCtx->GetDungeon(FOREST_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_FOREST_TEMPLE_BOSS_REGION, { [] { return ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, { [] { return ctx->GetDungeon(FOREST_TEMPLE)->IsMQ() && false; } }), Entrance(RR_FOREST_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Area( + areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region( "Forest Temple Boss Room", "Forest Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp index 05249def11a..4607f249f13 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp @@ -5,22 +5,22 @@ using namespace Rando; -void AreaTable_Init_GanonsCastle() { +void RegionTable_Init_GanonsCastle() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_GANONS_CASTLE_ENTRYWAY] = Area("Ganon's Castle Entryway", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GANONS_CASTLE_ENTRYWAY] = Region("Ganon's Castle Entryway", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_GANONS_CASTLE_LOBBY, {[]{return randoCtx->GetDungeon(GANONS_CASTLE)->IsVanilla();}}), - Entrance(RR_GANONS_CASTLE_MQ_LOBBY, {[]{return randoCtx->GetDungeon(GANONS_CASTLE)->IsMQ();}}), + Entrance(RR_GANONS_CASTLE_LOBBY, {[]{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}}), + Entrance(RR_GANONS_CASTLE_MQ_LOBBY, {[]{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}}), Entrance(RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(GANONS_CASTLE)->IsVanilla()) { - areaTable[RR_GANONS_CASTLE_LOBBY] = Area("Ganon's Castle Lobby", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(GANONS_CASTLE)->IsVanilla()) { + areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHEIK_HINT_GC, true), }, { @@ -32,72 +32,72 @@ void AreaTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}), - Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && - (logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && - (logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && - (logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && - (logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && - (logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}), - Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + Entrance(RR_GANONS_CASTLE_TOWER, {[]{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_CASTLE_DEKU_SCRUBS, {[]{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); - areaTable[RR_GANONS_CASTLE_DEKU_SCRUBS] = Area("Ganon's Castle Deku Scrubs", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_DEKU_SCRUBS] = Region("Ganon's Castle Deku Scrubs", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku()), }, {}); - areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Area("Ganon's Castle Forest Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->ForestTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->FireArrows || logic->DinsFire);}}), + EventAccess(&logic->ForestTrialClear, {[]{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->CanAdultDamage || logic->CanChildDamage), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanDamage()), }, {}); - areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Area("Ganon's Castle Fire Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Region("Ganon's Castle Fire Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}}), }, {}, {}); - areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Area("Ganon's Castle Water Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle;}}), - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || logic->BlueFire;}}), - EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || logic->BlueFire();}}), + EventAccess(&logic->WaterTrialClear, {[]{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), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), }, {}); - areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Area("Ganon's Castle Shadow Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Region("Ganon's Castle Shadow Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->ShadowTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->FireArrows && (randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->DinsFire && (randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))));}}), + 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))))));}}), }, { //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), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), }, {}); - areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->NutPot, {[]{return logic->NutPot || (((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), - EventAccess(&logic->SpiritTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash) || logic->CanUse(RG_HOOKSHOT));}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || (((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash()) || 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->CanJumpslash()) || logic->CanUse(RG_HOOKSHOT));}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslash), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslash()), + 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))), }, {}); - areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Area("Ganon's Castle Light Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->LightTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (randoCtx->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(RR_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), @@ -106,109 +106,109 @@ void AreaTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, true), 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, randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), + 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)), }, {}); } - areaTable[RR_GANONS_CASTLE_TOWER] = Area("Ganon's Castle Tower", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GANONS_CASTLE_TOWER] = Region("Ganon's Castle Tower", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GANONDORF_HINT, logic->BossKeyGanonsCastle && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), - LOCATION(RC_GANON, logic->HasBossSoul(RG_GANON_SOUL) && logic->BossKeyGanonsCastle && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MASTER_SWORD)), + LOCATION(RC_GANONDORF_HINT, logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GANON, logic->HasBossSoul(RG_GANON_SOUL) && logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MASTER_SWORD)), }, {}); /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(GANONS_CASTLE)->IsMQ()) { - areaTable[RR_GANONS_CASTLE_MQ_LOBBY] = Area("Ganon's Castle MQ Lobby", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(GANONS_CASTLE)->IsMQ()) { + areaTable[RR_GANONS_CASTLE_MQ_LOBBY] = Region("Ganon's Castle MQ Lobby", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHEIK_HINT_MQ_GC, true), }, { //Exits - Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return (logic->CanUse(RG_MASTER_SWORD) || (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword))));}}), + Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return (logic->CanUse(RG_MASTER_SWORD) || (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD)))));}}), Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}), - Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && - (logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && - (logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && - (logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && - (logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && - (logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}), - Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + Entrance(RR_GANONS_CASTLE_TOWER, {[]{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_CASTLE_MQ_DEKU_SCRUBS, {[]{return ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); - areaTable[RR_GANONS_CASTLE_MQ_DEKU_SCRUBS] = Area("Ganon's Castle MQ Deku Scrubs", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_DEKU_SCRUBS] = Region("Ganon's Castle MQ Deku Scrubs", "Ganon's Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku), - LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), }, {}); - areaTable[RR_GANONS_CASTLE_MQ_FOREST_TRIAL] = Area("Ganon's Castle MQ Forest Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_FOREST_TRIAL] = Region("Ganon's Castle MQ Forest Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_SONG_OF_TIME);}}), }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasFireSource), - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HookshotOrBoomerang), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasFireSource()), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HookshotOrBoomerang()), }, {}); - areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL] = Area("Ganon's Castle MQ Fire Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_FIRE_TRIAL] = Region("Ganon's Castle MQ Fire Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->HoverBoots || (randoCtx->GetTrickOption(RT_GANON_MQ_FIRE_TRIAL) && logic->CanUse(RG_HOOKSHOT)));}}), - //Trick: logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->HoverBoots || (LogicFireTrialMQ && logic->CanUse(RG_HOOKSHOT))) + EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GANON_MQ_FIRE_TRIAL) && logic->CanUse(RG_HOOKSHOT)));}}), + //Trick: logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (LogicFireTrialMQ && logic->CanUse(RG_HOOKSHOT))) }, {}, {}); - areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL] = Area("Ganon's Castle MQ Water Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL] = Region("Ganon's Castle MQ Water Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire && logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3);}}), - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle && logic->CanJumpslash);}}), + EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle() && logic->CanJumpslash());}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), }, {}); - areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL] = Area("Ganon's Castle MQ Shadow Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL] = Region("Ganon's Castle MQ Shadow Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->ShadowTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HoverBoots || (logic->Hookshot && (logic->HasFireSource || randoCtx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))));}}), - //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HoverBoots || (logic->Hookshot && (logic->HasFireSource || LogicShadowTrialMQ))) + EventAccess(&logic->ShadowTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || ctx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || LogicShadowTrialMQ))) }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->IsAdult && ((logic->Bow && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_HOVER_BOOTS) && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HasExplosives || logic->GoronBracelet || logic->CanUse(RG_DINS_FIRE))))), - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->IsAdult && logic->Bow && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HoverBoots || (logic->Hookshot && (logic->HasFireSource || randoCtx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))))), - //Trick: logic->IsAdult && logic->Bow && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HoverBoots || (logic->Hookshot && (logic->HasFireSource || LogicShadowTrialMQ))) + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->IsAdult && ((logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE))))), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || ctx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))))), + //Trick: logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || LogicShadowTrialMQ))) }, {}); - areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL] = Area("Ganon's Castle MQ Spirit Castle", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL] = Region("Ganon's Castle MQ Spirit Castle", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->SpiritTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->FireArrows && logic->MirrorShield) || randoCtx->GetOption(RSK_SUNLIGHT_ARROWS));}}), - EventAccess(&logic->NutPot, {[]{return logic->NutPot || (logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && ((logic->CanUse(RG_FIRE_ARROWS) && logic->MirrorShield) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), + EventAccess(&logic->SpiritTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || ctx->GetOption(RSK_SUNLIGHT_ARROWS));}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || (logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, logic->IsAdult && (logic->Bow || randoCtx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, logic->IsAdult && logic->Hammer && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), }, {}); - areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL] = Area("Ganon's Castle MQ Light Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL] = Region("Ganon's Castle MQ Light Trial", "Ganons Castle", RA_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->LightTrialClear, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->Hookshot || randoCtx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL));}}), - //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->Hookshot || LogicLightTrialMQ) + EventAccess(&logic->LightTrialClear, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || LogicLightTrialMQ) }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_ZELDAS_LULLABY)), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp index c0a2ab2bc16..686c7c11db0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp @@ -4,38 +4,38 @@ using namespace Rando; -void AreaTable_Init_GerudoTrainingGrounds() { +void RegionTable_Init_GerudoTrainingGrounds() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY] = Area("Gerudo Training Grounds Entryway", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY] = Region("Gerudo Training Grounds Entryway", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_LOBBY, {[]{return randoCtx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla();}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, {[]{return randoCtx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ();}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla();}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ();}}), Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla()) { - areaTable[RR_GERUDO_TRAINING_GROUNDS_LOBBY] = Area("Gerudo Training Grounds Lobby", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla()) { + areaTable[RR_GERUDO_TRAINING_GROUNDS_LOBBY] = Region("Gerudo Training Grounds Lobby", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || randoCtx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT));}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_LOBBY, []{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasExplosives;});}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_LOBBY, []{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasExplosives();});}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, {[]{return true;}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE] = Area("Gerudo Training Grounds Central Maze", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE] = Region("Gerudo Training Grounds Central Maze", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3) && (randoCtx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 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_GROUNDS, 4)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 6)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 7)), @@ -45,7 +45,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 9);}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT] = Area("Gerudo Training Grounds Central Maze Right", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Grounds Central Maze Right", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, true), @@ -56,26 +56,26 @@ void AreaTable_Init_GerudoTrainingGrounds() { Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM] = Area("Gerudo Training Grounds Lava Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM] = Region("Gerudo Training Grounds Lava Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->IronBoots && logic->WaterTimer >= 24), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM] = Area("Gerudo Training Grounds Hammer Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM] = Region("Gerudo Training Grounds Hammer Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAdultAttack || logic->CanChildAttack), - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->CanTakeDamage && randoCtx->GetTrickOption(RT_FLAMING_CHESTS))), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW);}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER] = Area("Gerudo Training Grounds Eye Statue Lower", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER] = Region("Gerudo Training Grounds Eye Statue Lower", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), }, { @@ -83,7 +83,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return true;}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER] = Area("Gerudo Training Grounds Eye Statue Upper", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER] = Region("Gerudo Training Grounds Eye Statue Upper", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW)), }, { @@ -91,44 +91,44 @@ void AreaTable_Init_GerudoTrainingGrounds() { Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return true;}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM] = Area("Gerudo Training Grounds Heavy Block Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM] = Region("Gerudo Training Grounds Heavy Block Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanJumpslash), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanJumpslash()), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, {[]{return (randoCtx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, {[]{return (randoCtx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_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_GROUNDS_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);}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM] = Area("Gerudo Training Grounds Like Like Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM] = Region("Gerudo Training Grounds Like Like Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslash), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslash), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslash), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslash), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslash()), }, {}); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ()) { - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY] = Area("Gerudo Training Grounds MQ Lobby", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ()) { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY] = Region("Gerudo Training Grounds MQ Lobby", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, randoCtx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 1)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return logic->HasFireSource;});}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return logic->HasFireSource();});}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT));});}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE] = Area("Gerudo Training Grounds MQ Right Side", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE] = Region("Gerudo Training Grounds MQ Right Side", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, { //Events //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), }, { @@ -136,55 +136,55 @@ void AreaTable_Init_GerudoTrainingGrounds() { LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (logic->Bow || (logic->CanUse(RG_LONGSHOT) && logic->HasFireSource)) && logic->CanUse(RG_HOVER_BOOTS) && logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_LONGSHOT) && logic->HasFireSource())) && logic->CanUse(RG_HOVER_BOOTS) && logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER] = Area("Gerudo Training Grounds MQ Underwater", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER] = Region("Gerudo Training Grounds MQ Underwater", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource && logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer >= 24 && logic->CanTakeDamage), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), }, {}); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE] = Area("Gerudo Training Grounds MQ Left Side", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE] = Region("Gerudo Training Grounds MQ Left Side", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->HasExplosives), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->HasExplosives()), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || randoCtx->GetTrickOption(RT_GTG_MQ_WIHTOUT_HOOKSHOT) || (randoCtx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || ctx->GetTrickOption(RT_GTG_MQ_WIHTOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), //Trick: (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM] = Area("Gerudo Training Grounds MQ Stalfos Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM] = Region("Gerudo Training Grounds MQ Stalfos Room", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle;}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), }, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (randoCtx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire && (logic->CanUse(RG_SONG_OF_TIME) || (randoCtx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (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->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}}), //Trick: logic->IsAdult && (LogicLensGtgMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire && (logic->CanUse(RG_SONG_OF_TIME) || (LogicGtgFakeWall && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS] = Area("Gerudo Training Grounds MQ Back Areas", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS] = Region("Gerudo Training Grounds MQ Back Areas", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasExplosives), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasExplosives()), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT] = Area("Gerudo Training Grounds MQ Central Maze Right", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Grounds MQ Central Maze Right", "Gerudo Training Grounds", RA_GERUDO_TRAINING_GROUND, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, true), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3)), }, { //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->Bow));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)));}}), Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index 5913e2d3b37..ec9790ed1a4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -3,30 +3,30 @@ using namespace Rando; -void AreaTable_Init_GerudoValley() { - areaTable[RR_GERUDO_VALLEY] = Area("Gerudo Valley", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { +void RegionTable_Init_GerudoValley() { + areaTable[RR_GERUDO_VALLEY] = Region("Gerudo Valley", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), 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->CanRideEpona || logic->CanUse(RG_LONGSHOT) || randoCtx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue)) || (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_OPEN) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), }); - areaTable[RR_GV_UPPER_STREAM] = Area("GV Upper Stream", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { + areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->Swim),//can use cucco as child - LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanPlantBugs && logic->CanChildAttack), + LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child + LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_GV_GOSSIP_STONE, true), }, { @@ -34,19 +34,19 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), }); - areaTable[RR_GV_LOWER_STREAM] = Area("GV Lower Stream", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild || logic->Swim;}}),//can use cucco as child + Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE);}}),//can use cucco as child }); - areaTable[RR_GV_GROTTO_LEDGE] = Area("GV Grotto Ledge", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), Entrance(RR_GV_OCTOROK_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), Entrance(RR_GV_CRATE_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[RR_GV_CRATE_LEDGE] = Area("GV Crate Ledge", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GV_CRATE_LEDGE] = Region("GV Crate Ledge", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GV_CRATE_FREESTANDING_POH, true), }, { @@ -54,80 +54,80 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), }); - areaTable[RR_GV_FORTRESS_SIDE] = Area("GV Fortress Side", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { + areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BrokenSwordAccess, {[]{return logic->IsAdult && (logic->PoachersSawAccess || logic->PoachersSaw);}}), + EventAccess(&logic->BrokenSwordAccess, {[]{return logic->IsAdult && (logic->PoachersSawAccess || logic->CanUse(RG_POACHERS_SAW));}}), }, { //Locations LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->PoachersSaw), - LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), - Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanRideEpona || logic->CanUse(RG_LONGSHOT) || randoCtx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue;}}), + Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue;}}), Entrance(RR_GV_CARPENTER_TENT, {[]{return logic->IsAdult;}}), - Entrance(RR_GV_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormGrotto;}}), + Entrance(RR_GV_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), Entrance(RR_GV_CRATE_LEDGE, {[]{return false;}}), }); - areaTable[RR_GV_CARPENTER_TENT] = Area("GV Carpenter Tent", "GV Carpenter Tent", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_CARPENTER_TENT] = Region("GV Carpenter Tent", "GV Carpenter Tent", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[RR_GV_OCTOROK_GROTTO] = Area("GV Octorok Grotto", "GV Octorok Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), }); - areaTable[RR_GV_STORMS_GROTTO] = Area("GV Storms Grotto", "GV Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GV_STORMS_GROTTO] = Region("GV Storms Grotto", "GV Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GV_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku), - LOCATION(RC_GV_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku), - LOCATION(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[RR_GERUDO_FORTRESS] = Area("Gerudo Fortress", "Gerudo Fortress", RA_GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GERUDO_FORTRESS] = Region("Gerudo Fortress", "Gerudo Fortress", RA_GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->CarpenterRescue, {[]{return logic->CanFinishGerudoFortress;}}), - EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->GerudoToken;}}), - EventAccess(&logic->GtG_GateOpen, {[]{return logic->GtG_GateOpen || (logic->IsAdult && logic->GerudoToken && logic->ChildsWallet);}}), + EventAccess(&logic->CarpenterRescue, {[]{return logic->CanFinishGerudoFortress();}}), + EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}}), + EventAccess(&logic->GtG_GateOpen, {[]{return logic->GtG_GateOpen || (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}}), }, { //Locations LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GF_HBA_1000_POINTS, logic->ChildsWallet && logic->GerudoToken && logic->CanRideEpona && logic->Bow && logic->AtDay), - LOCATION(RC_GF_HBA_1500_POINTS, logic->ChildsWallet && logic->GerudoToken && logic->CanRideEpona && logic->Bow && logic->AtDay), + LOCATION(RC_GF_HBA_1000_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_HBA_1500_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->GerudoToken || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || randoCtx->GetTrickOption(RT_GF_KITCHEN))), + LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress), - LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang && logic->GerudoToken && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->AtNight && (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)) && (logic->GerudoToken || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || randoCtx->GetTrickOption(RT_GF_KITCHEN) || randoCtx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS), + LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), + LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->AtNight && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), Entrance(RR_GF_OUTSIDE_GATE, {[]{return logic->GF_GateOpen;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return logic->GtG_GateOpen && (logic->IsAdult || randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}}), - Entrance(RR_GF_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormGrotto;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}}), + Entrance(RR_GF_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_GF_OUTSIDE_GATE] = Area("GF Outside Gate", "Gerudo Fortress", RA_GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GF_OUTSIDE_GATE] = Region("GF Outside Gate", "Gerudo Fortress", RA_GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->GerudoToken && (randoCtx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) || randoCtx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) /*|| ShuffleSpecialIndoorEntrances*/);}}), + EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) /*|| ShuffleSpecialIndoorEntrances*/);}}), }, {}, { //Exits - Entrance(RR_GERUDO_FORTRESS, {[]{return (logic->IsAdult && (logic->Hookshot || !randoCtx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES))) || logic->GF_GateOpen;}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || !ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES))) || logic->GF_GateOpen;}}), Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return true;}}), }); - areaTable[RR_GF_STORMS_GROTTO] = Area("GF Storms Grotto", "GF Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", "GF Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { @@ -135,54 +135,54 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), }); - areaTable[RR_WASTELAND_NEAR_FORTRESS] = Area("Wasteland Near Fortress", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WASTELAND_NEAR_FORTRESS] = Region("Wasteland Near Fortress", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_GF_OUTSIDE_GATE, {[]{return true;}}), - Entrance(RR_HAUNTED_WASTELAND, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || randoCtx->GetTrickOption(RT_HW_CROSSING);}}), + Entrance(RR_HAUNTED_WASTELAND, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}}), }); - areaTable[RR_HAUNTED_WASTELAND] = Area("Haunted Wasteland", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HAUNTED_WASTELAND] = Region("Haunted Wasteland", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), - EventAccess(&logic->CarpetMerchant, {[]{return logic->AdultsWallet && (logic->CanJumpslash || logic->CanUse(RG_HOVER_BOOTS));}}), + EventAccess(&logic->CarpetMerchant, {[]{return logic->HasItem(RG_ADULT_WALLET) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}), }, { //Locations - LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource), + LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CarpetMerchant), - LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang), + LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return randoCtx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), - Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || randoCtx->GetTrickOption(RT_HW_CROSSING);}}), + Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return ctx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}}), }); - areaTable[RR_WASTELAND_NEAR_COLOSSUS] = Area("Wasteland Near Colossus", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WASTELAND_NEAR_COLOSSUS] = Region("Wasteland Near Colossus", "Haunted Wasteland", RA_HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), - Entrance(RR_HAUNTED_WASTELAND, {[]{return randoCtx->GetTrickOption(RT_HW_REVERSE) || false;}}), + Entrance(RR_HAUNTED_WASTELAND, {[]{return ctx->GetTrickOption(RT_HW_REVERSE) || false;}}), }); - areaTable[RR_DESERT_COLOSSUS] = Area("Desert Colossus", "Desert Colossus", RA_DESERT_COLOSSUS, DAY_NIGHT_CYCLE, { + areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", "Desert Colossus", RA_DESERT_COLOSSUS, DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPond, {[]{return logic->FairyPond || logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), - LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanPlantBugs && logic->CanChildAttack), - LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAdultAttack) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS), + LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives;}}), + Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return true;}}), Entrance(RR_COLOSSUS_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY] = Area("Desert Colossus From Spirit Entryway", "Desert Colossus", RA_DESERT_COLOSSUS, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY] = Region("Desert Colossus From Spirit Entryway", "Desert Colossus", RA_DESERT_COLOSSUS, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHEIK_AT_COLOSSUS, true), }, { @@ -190,7 +190,7 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Area("Colossus Great Fairy Fountain", "Colossus Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Region("Colossus Great Fairy Fountain", "Colossus Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { @@ -198,11 +198,11 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[RR_COLOSSUS_GROTTO] = Area("Colossus Grotto", "Colossus Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_COLOSSUS_GROTTO] = Region("Colossus Grotto", "Colossus Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku), - LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku), - LOCATION(RC_COLOSSUS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_COLOSSUS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 860b90e8b80..2e906c7aade 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -3,14 +3,14 @@ using namespace Rando; -void AreaTable_Init_HyruleField() { - areaTable[RR_HYRULE_FIELD] = Area("Hyrule Field", "Hyrule Field", RA_HYRULE_FIELD, DAY_NIGHT_CYCLE, { +void RegionTable_Init_HyruleField() { + areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", "Hyrule Field", RA_HYRULE_FIELD, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanRideEpona && logic->HasBottle;}}), + EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}}), }, { //Locations - LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->HasAllStones), - LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->HasAllStones), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3), }, { //Exits Entrance(RR_LW_BRIDGE, {[]{return true;}}), @@ -20,72 +20,72 @@ void AreaTable_Init_HyruleField() { Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), Entrance(RR_ZR_FRONT, {[]{return true;}}), Entrance(RR_LON_LON_RANCH, {[]{return true;}}), - Entrance(RR_HF_SOUTHEAST_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->CanBlastOrSmash;});}}), + Entrance(RR_HF_SOUTHEAST_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), Entrance(RR_HF_OPEN_GROTTO, {[]{return true;}}), - Entrance(RR_HF_INSIDE_FENCE_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), - Entrance(RR_HF_COW_GROTTO, {[]{return (logic->CanUse(RG_MEGATON_HAMMER) || logic->IsChild) && logic->CanOpenBombGrotto;}}), - Entrance(RR_HF_NEAR_MARKET_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_HF_FAIRY_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_HF_NEAR_KAK_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), - Entrance(RR_HF_TEKTITE_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), + Entrance(RR_HF_INSIDE_FENCE_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_COW_GROTTO, {[]{return (logic->CanUse(RG_MEGATON_HAMMER) || logic->IsChild) && logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_NEAR_MARKET_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), + Entrance(RR_HF_FAIRY_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), + Entrance(RR_HF_NEAR_KAK_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_TEKTITE_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), }); - areaTable[RR_HF_SOUTHEAST_GROTTO] = Area("HF Southeast Grotto", "HF Southeast Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", "HF Southeast Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), - LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_OPEN_GROTTO] = Area("HF Open Grotto", "HF Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", "HF Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), - LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_INSIDE_FENCE_GROTTO] = Area("HF Inside Fence Grotto", "HF Inside Fence Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_INSIDE_FENCE_GROTTO] = Region("HF Inside Fence Grotto", "HF Inside Fence Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku), - LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives), + LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku()), + LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_COW_GROTTO] = Area("HF Cow Grotto", "HF Cow Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_HF_GS_COW_GROTTO, logic->HasFireSource && logic->HookshotOrBoomerang), - LOCATION(RC_HF_COW_GROTTO_COW, logic->HasFireSource && logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, logic->HasFireSource), + LOCATION(RC_HF_GS_COW_GROTTO, logic->HasFireSource() && logic->HookshotOrBoomerang()), + LOCATION(RC_HF_COW_GROTTO_COW, logic->HasFireSource() && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, logic->HasFireSource()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_NEAR_MARKET_GROTTO] = Area("HF Near Market Grotto", "HF Near Market Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", "HF Near Market Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_FAIRY_GROTTO] = Area("HF Fairy Grotto", "HF Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", "HF Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { @@ -93,71 +93,71 @@ void AreaTable_Init_HyruleField() { Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_NEAR_KAK_GROTTO] = Area("HF Near Kak Grotto", "HF Near Kak Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_NEAR_KAK_GROTTO] = Region("HF Near Kak Grotto", "HF Near Kak Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_HF_GS_NEAR_KAK_GROTTO, logic->HookshotOrBoomerang), + LOCATION(RC_HF_GS_NEAR_KAK_GROTTO, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_TEKTITE_GROTTO] = Area("HF Tektite Grotto", "HF Tektite Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_TEKTITE_GROTTO] = Region("HF Tektite Grotto", "HF Tektite Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, logic->ProgressiveScale >= 2 || logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS)), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_LAKE_HYLIA] = Area("Lake Hylia", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, { + areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), - EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs);}}), - EventAccess(&logic->ChildScarecrow, {[]{return logic->ChildScarecrow || (logic->IsChild && logic->Ocarina && logic->OcarinaButtons >= 2);}}), - EventAccess(&logic->AdultScarecrow, {[]{return logic->AdultScarecrow || (logic->IsAdult && logic->Ocarina && logic->OcarinaButtons >= 2);}}), + EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}}), + EventAccess(&logic->ChildScarecrow, {[]{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), + EventAccess(&logic->AdultScarecrow, {[]{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), }, { //Locations - LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->CanDive), + LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), LOCATION(RC_LH_SUN, logic->IsAdult && logic->WaterTempleClear && 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->CanPlantBugs && logic->CanChildAttack), - LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->HookshotOrBoomerang || (randoCtx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslash)) && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanChildAttack && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslash())) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanAttack() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_LH_LAB_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), - Entrance(RR_ZORAS_DOMAIN, {[]{return logic->IsChild && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), Entrance(RR_LH_OWL_FLIGHT, {[]{return logic->IsChild;}}), Entrance(RR_LH_FISHING_ISLAND, {[]{return logic->IsChild || logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA) || logic->WaterTempleClear;}}), Entrance(RR_LH_LAB, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (randoCtx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->ProgressiveScale >= 2)) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->ProgressiveScale >= 2));}}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}}), Entrance(RR_LH_GROTTO, {[]{return true;}}), }); - areaTable[RR_LH_FISHING_ISLAND] = Area("LH Fishing Island", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), Entrance(RR_LH_FISHING_HOLE, {[]{return true;}}), }); - areaTable[RR_LH_OWL_FLIGHT] = Area("LH Owl Flight", "Lake Hylia", RA_LAKE_HYLIA, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_LH_OWL_FLIGHT] = Region("LH Owl Flight", "Lake Hylia", RA_LAKE_HYLIA, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_LH_LAB] = Area("LH Lab", "LH Lab", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_LH_LAB] = Region("LH Lab", "LH Lab", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->EyedropsAccess, {[]{return logic->EyedropsAccess || (logic->IsAdult && (logic->EyeballFrogAccess || (logic->EyeballFrog && logic->DisableTradeRevert)));}}), + EventAccess(&logic->EyedropsAccess, {[]{return logic->EyedropsAccess || (logic->IsAdult && (logic->EyeballFrogAccess || (logic->CanUse(RG_EYEBALL_FROG) && logic->DisableTradeRevert)));}}), }, { //Locations - LOCATION(RC_LH_LAB_DIVE, logic->ProgressiveScale >= 2 || (randoCtx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->EyeballFrog), + LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)), }, { //Exits @@ -165,72 +165,72 @@ void AreaTable_Init_HyruleField() { }); // TODO: should some of these helpers be done via events instead? - areaTable[RR_LH_FISHING_HOLE] = Area("LH Fishing Hole", "LH Fishing Hole", RA_NONE, DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LH_FISHING_HOLE] = Region("LH Fishing Hole", "LH Fishing Hole", RA_NONE, DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LH_CHILD_FISHING, logic->CanFish && logic->IsChild), - LOCATION(RC_LH_CHILD_FISH_1, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_2, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_3, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_4, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_5, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_6, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_7, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_8, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_9, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_10, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_11, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_12, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_13, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_14, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_FISH_15, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_LOACH_1, logic->CanGetChildFish), - LOCATION(RC_LH_CHILD_LOACH_2, logic->CanGetChildFish), - LOCATION(RC_LH_ADULT_FISHING, logic->CanFish && logic->IsAdult), - LOCATION(RC_LH_ADULT_FISH_1, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_2, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_3, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_4, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_5, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_6, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_7, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_8, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_9, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_10, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_11, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_12, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_13, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_14, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_FISH_15, logic->CanGetAdultFish), - LOCATION(RC_LH_ADULT_LOACH, logic->CanGetAdultFish), - LOCATION(RC_LH_HYRULE_LOACH, logic->CanFish), + LOCATION(RC_LH_CHILD_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->IsChild), + LOCATION(RC_LH_CHILD_FISH_1, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_2, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_3, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_4, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_5, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_6, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_7, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_8, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_9, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_10, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_11, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_12, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_13, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_14, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_15, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_1, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_2, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_ADULT_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult), + LOCATION(RC_LH_ADULT_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_HYRULE_LOACH, logic->CanUse(RG_FISHING_POLE)), LOCATION(RC_FISHING_POLE_HINT, true), }, { //Exits Entrance(RR_LH_FISHING_ISLAND, {[]{return true;}}), }); - areaTable[RR_LH_GROTTO] = Area("LH Grotto", "LH Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LH_GROTTO] = Region("LH Grotto", "LH Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LH_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku), - LOCATION(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku), - LOCATION(RC_LH_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku), - LOCATION(RC_LH_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_LH_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - areaTable[RR_LON_LON_RANCH] = Area("Lon Lon Ranch", "Lon Lon Ranch", RA_LON_LON_RANCH, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", "Lon Lon Ranch", RA_LON_LON_RANCH, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->Epona, {[]{return logic->Epona || ((logic->ChildsWallet || randoCtx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}}), - EventAccess(&logic->LinksCow, {[]{return logic->LinksCow || (logic->ChildsWallet && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}}), + EventAccess(&logic->FreedEpona, {[]{return logic->FreedEpona || ((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->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}}), }, { //Locations - LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->ZeldasLetter && logic->Ocarina && logic->AtDay), + 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_RAIN_SHED, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -240,15 +240,15 @@ void AreaTable_Init_HyruleField() { Entrance(RR_LLR_GROTTO, {[]{return logic->IsChild;}}), }); - areaTable[RR_LLR_TALONS_HOUSE] = Area("LLR Talons House", "LLR Talons House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_TALONS_HOUSE] = Region("LLR Talons House", "LLR Talons House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LLR_TALONS_CHICKENS, logic->ChildsWallet && logic->IsChild && logic->AtDay && logic->ZeldasLetter), + LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasItem(RG_ZELDAS_LETTER)), }, { //Exits Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[RR_LLR_STABLES] = Area("LLR Stables", "LLR Stables", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_STABLES] = Region("LLR Stables", "LLR Stables", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_LLR_STABLES_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_LLR_STABLES_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), @@ -257,7 +257,7 @@ void AreaTable_Init_HyruleField() { Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[RR_LLR_TOWER] = Area("LLR Tower", "LLR Tower", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_TOWER] = Region("LLR Tower", "LLR Tower", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild), LOCATION(RC_LLR_TOWER_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)), @@ -267,12 +267,12 @@ void AreaTable_Init_HyruleField() { Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[RR_LLR_GROTTO] = Area("LLR Grotto", "LLR Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_GROTTO] = Region("LLR Grotto", "LLR Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku), - LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku), - LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku), - LOCATION(RC_LLR_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_LLR_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_LON_LON_RANCH, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp index 7f5873ba17a..feb932e5f90 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp @@ -4,80 +4,80 @@ using namespace Rando; -void AreaTable_Init_IceCavern() { +void RegionTable_Init_IceCavern() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_ICE_CAVERN_ENTRYWAY] = Area("Ice Cavern Entryway", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ICE_CAVERN_ENTRYWAY] = Region("Ice Cavern Entryway", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_ICE_CAVERN_BEGINNING, {[]{return randoCtx->GetDungeon(ICE_CAVERN)->IsVanilla();}}), - Entrance(RR_ICE_CAVERN_MQ_BEGINNING, {[]{return randoCtx->GetDungeon(ICE_CAVERN)->IsMQ() && logic->CanUseProjectile;}}), + Entrance(RR_ICE_CAVERN_BEGINNING, {[]{return ctx->GetDungeon(ICE_CAVERN)->IsVanilla();}}), + Entrance(RR_ICE_CAVERN_MQ_BEGINNING, {[]{return ctx->GetDungeon(ICE_CAVERN)->IsMQ() && logic->CanUseProjectile();}}), Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(ICE_CAVERN)->IsVanilla()) { - areaTable[RR_ICE_CAVERN_BEGINNING] = Area("Ice Cavern Beginning", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(ICE_CAVERN)->IsVanilla()) { + areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(RR_ICE_CAVERN_MAIN, {[]{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}}), + Entrance(RR_ICE_CAVERN_MAIN, {[]{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}}), }); - areaTable[RR_ICE_CAVERN_MAIN] = Area("Ice Cavern", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ICE_CAVERN_MAIN] = Region("Ice Cavern", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->IsAdult && logic->HasBottle);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->IsAdult && logic->HasBottle());}}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire && logic->IsAdult), - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire), - LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire && (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE))), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire && (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE)) && logic->IsAdult), - LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire), - LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang), - LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire && logic->HookshotOrBoomerang), - LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->BlueFire && (logic->HookshotOrBoomerang || (randoCtx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE)) && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->BlueFire() && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), }, {}); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(ICE_CAVERN)->IsMQ()) { - areaTable[RR_ICE_CAVERN_MQ_BEGINNING] = Area("Ice Cavern MQ Beginning", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(ICE_CAVERN)->IsMQ()) { + areaTable[RR_ICE_CAVERN_MQ_BEGINNING] = Region("Ice Cavern MQ Beginning", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE) || (logic->HasExplosives && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)));}}), - Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return logic->IsAdult && logic->BlueFire;}}), - Entrance(RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return logic->BlueFire;}}), + Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)));}}), + Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return logic->IsAdult && logic->BlueFire();}}), + Entrance(RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return logic->BlueFire();}}), }); - areaTable[RR_ICE_CAVERN_MQ_MAP_ROOM] = Area("Ice Cavern MQ Map Room", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ICE_CAVERN_MQ_MAP_ROOM] = Region("Ice Cavern MQ Map Room", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle && logic->CanJumpslash);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle() && logic->CanJumpslash());}}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire && (logic->CanJumpslash || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives || logic->CanUseProjectile)), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUseProjectile())), }, {}); - areaTable[RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION] = Area("Ice Cavern MQ Iron Boots Region", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION] = Region("Ice Cavern MQ Iron Boots Region", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->IsAdult && (logic->CanJumpslash || logic->CanUse(RG_MEGATON_HAMMER))), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->IsAdult && (logic->CanJumpslash || logic->CanUse(RG_MEGATON_HAMMER))), - LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, logic->CanAdultAttack || logic->CanChildAttack), - LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->HoverBoots && logic->CanUse(RG_LONGSHOT)) || (randoCtx->GetTrickOption(RT_ICE_MQ_SCARECROW) && logic->IsAdult)), - //Tricks: (logic->CanUse(RG_SCARECROW) || (logic->HoverBoots && logic->CanUse(RG_LONGSHOT)) || LogicIceMQScarecrow) && logic->IsAdult + LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->IsAdult && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER))), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->IsAdult && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER))), + LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, logic->CanAttack()), + LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_ICE_MQ_SCARECROW) && logic->IsAdult)), + //Tricks: (logic->CanUse(RG_SCARECROW) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || LogicIceMQScarecrow) && logic->IsAdult }, {}); - areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Area("Ice Cavern MQ Compass Room", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", "Ice Cavern", RA_ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), - LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives), - LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS)), + LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), + LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS)), //Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicIceMQRedIceGS }, {}); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp index 036a522b0f7..53076bcfe7b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp @@ -4,36 +4,36 @@ using namespace Rando; -void AreaTable_Init_JabuJabusBelly() { +void RegionTable_Init_JabuJabusBelly() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_JABU_JABUS_BELLY_ENTRYWAY] = Area("Jabu Jabus Belly Entryway", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_ENTRYWAY] = Region("Jabu Jabus Belly Entryway", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla();}}), - Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsMQ();}}), + Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla();}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ();}}), Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla()) { - areaTable[RR_JABU_JABUS_BELLY_BEGINNING] = Area("Jabu Jabus Belly Beginning", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla()) { + areaTable[RR_JABU_JABUS_BELLY_BEGINNING] = Region("Jabu Jabus Belly Beginning", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return logic->CanUseProjectile;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return logic->CanUseProjectile();}}), }); - areaTable[RR_JABU_JABUS_BELLY_LIFT_MIDDLE] = Area("Jabu Jabus Belly Lift Middle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_LIFT_MIDDLE] = Region("Jabu Jabus Belly Lift Middle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return HasAccessTo(RR_JABU_JABUS_BELLY_LIFT_UPPER) || (randoCtx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return HasAccessTo(RR_JABU_JABUS_BELLY_LIFT_UPPER) || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}), }); - areaTable[RR_JABU_JABUS_BELLY_MAIN_UPPER] = Area("Jabu Jabus Belly Main Upper", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_MAIN_UPPER] = Region("Jabu Jabus Belly Main Upper", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), @@ -41,10 +41,10 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, {[]{return Here(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_MAIN_LOWER] = Area("Jabu Jabus Belly Main Lower", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MAIN_LOWER] = Region("Jabu Jabus Belly Main Lower", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, logic->HookshotOrBoomerang), - LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->HookshotOrBoomerang), + LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, logic->HookshotOrBoomerang()), + LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), @@ -52,7 +52,7 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR] = Area("Jabu Jabus Belly Shabomb Corridor", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR] = Region("Jabu Jabus Belly Shabomb Corridor", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { @@ -60,11 +60,11 @@ void AreaTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, true), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return logic->Swim;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return logic->Swim && logic->CanUseProjectile;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return logic->HasItem(RG_BRONZE_SCALE) && logic->CanUseProjectile();}}), }); - areaTable[RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM] = Area("Jabu Jabus Belly Lower Side Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM] = Region("Jabu Jabus Belly Lower Side Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_HOVER_BOOTS));}}), }, {}, { @@ -72,16 +72,16 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_LIFT_LOWER] = Area("Jabu Jabus Belly Lift Lower", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_LIFT_LOWER] = Region("Jabu Jabus Belly Lift Lower", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->Swim && (logic->IsChild || logic->CanDive || randoCtx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku), + 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()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_FORKED_CORRIDOR] = Area("Jabu Jabus Belly Forked Corridor", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_FORKED_CORRIDOR] = Region("Jabu Jabus Belly Forked Corridor", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_BOOMERANG_ROOM, {[]{return true;}}), @@ -91,7 +91,7 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, {[]{return Here(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_BOOMERANG_ROOM] = Area("Jabu Jabus Belly Boomerang Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_BOOMERANG_ROOM] = Region("Jabu Jabus Belly Boomerang Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, true), }, { @@ -99,7 +99,7 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_MAP_ROOM] = Area("Jabu Jabus Belly Map Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MAP_ROOM] = Region("Jabu Jabus Belly Map Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->CanUse(RG_BOOMERANG)), }, { @@ -107,31 +107,31 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_COMPASS_ROOM] = Area("Jabu Jabus Belly Compass Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_COMPASS_ROOM] = Region("Jabu Jabus Belly Compass Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanAttack()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_BLUE_TENTACLE] = Area("Jabu Jabus Belly Blue Tentacle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_BLUE_TENTACLE] = Region("Jabu Jabus Belly Blue Tentacle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_GREEN_TENTACLE] = Area("Jabu Jabus Belly Green Tentacle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_GREEN_TENTACLE] = Region("Jabu Jabus Belly Green Tentacle", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_ROOM] = Area("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_ROOM] = Region("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return Here(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, []{return (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_NUTS)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS));});}}), }); - areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Area("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Region("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), @@ -140,32 +140,32 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_LIFT_UPPER, {[]{return logic->CanUse(RG_BOOMERANG);}}), }); - areaTable[RR_JABU_JABUS_BELLY_LIFT_UPPER] = Area("Jabu Jabus Belly Lift Upper", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_LIFT_UPPER] = Region("Jabu Jabus Belly Lift Upper", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Area("Jabu Jabus Belly Near Boss Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Region("Jabu Jabus Belly Near Boss Room", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanAdultAttack || logic->CanChildAttack), + LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanAttack()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && ((logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)))) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->Bombs)));}}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && ((logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsMQ()) { - areaTable[RR_JABU_JABUS_BELLY_MQ_BEGINNING] = Area("Jabu Jabus Belly MQ Beginning", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ()) { + areaTable[RR_JABU_JABUS_BELLY_MQ_BEGINNING] = Region("Jabu Jabus Belly MQ Beginning", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->CanBlastOrSmash), + LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits @@ -173,43 +173,43 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_BEGINNING, []{return logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_MAIN] = Area("Jabu Jabus Belly MQ Main", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_MAIN] = Region("Jabu Jabus Belly MQ Main", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) || ChildCanAccess(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->CanDive || logic->CanUse(RG_IRON_BOOTS) || - randoCtx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (randoCtx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG)))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || + ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG)))), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_STICKS) || logic->Bombs), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, logic->CanUse(RG_SONG_OF_TIME) || (randoCtx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_BOMB_BAG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG))), //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicJabuMQSoTGS && logic->IsChild && logic->CanUse(RG_BOOMERANG)) }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return logic->HasExplosives && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_BOOMERANG);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return logic->HasExplosives() && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_BOOMERANG);}}), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_DEPTHS] = Area("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_DEPTHS] = Region("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->Swim && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, (randoCtx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) || Here(RR_JABU_JABUS_BELLY_MQ_MAIN, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT);})), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->HasItem(RG_BRONZE_SCALE) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, (ctx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) || Here(RR_JABU_JABUS_BELLY_MQ_MAIN, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT);})), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->KokiriSword);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_KOKIRI_SWORD));}}), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_BOSS_AREA] = Area("Jabu Jabus Belly MQ Boss Area", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_JABU_JABUS_BELLY_MQ_BOSS_AREA] = Region("Jabu Jabus Belly MQ Boss Region", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG)), LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (randoCtx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), @@ -221,20 +221,20 @@ void AreaTable_Init_JabuJabusBelly() { | BOSS ROOM | ---------------------------*/ areaTable[RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY] = - Area("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", RA_JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, { [] { return randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla(); } }), - Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, { [] { return randoCtx->GetDungeon(JABU_JABUS_BELLY)->IsMQ(); } }), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla(); } }), + Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, { [] { return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ(); } }), Entrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, { [] { return true; } }), }); areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = - Area("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", RA_NONE, NO_DAY_NIGHT_CYCLE, + Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events //todo: add pot kill trick EventAccess(&logic->JabuJabusBellyClear, - { [] { return logic->JabuJabusBellyClear || (logic->HasBossSoul(RG_BARINADE_SOUL) && (logic->CanUse(RG_BOOMERANG) && logic->CanJumpslash)); } }), + { [] { return logic->JabuJabusBellyClear || (logic->HasBossSoul(RG_BARINADE_SOUL) && (logic->CanUse(RG_BOOMERANG) && logic->CanJumpslash())); } }), }, { // Locations diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp index b0452e41938..9475547f724 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -3,23 +3,23 @@ using namespace Rando; -void AreaTable_Init_Kakariko() { - areaTable[RR_KAKARIKO_VILLAGE] = Area("Kakariko Village", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, { +void RegionTable_Init_Kakariko() { + areaTable[RR_KAKARIKO_VILLAGE] = Region("Kakariko Village", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->CojiroAccess, {[]{return logic->CojiroAccess || (logic->IsAdult && logic->WakeUpAdultTalon);}}), EventAccess(&logic->BugRock, {[]{return true;}}), - EventAccess(&logic->KakarikoVillageGateOpen, {[]{return logic->KakarikoVillageGateOpen || (logic->IsChild && (logic->ZeldasLetter || randoCtx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN)));}}), + EventAccess(&logic->KakarikoVillageGateOpen, {[]{return logic->KakarikoVillageGateOpen || (logic->IsChild && (logic->HasItem(RG_ZELDAS_LETTER) || ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN)));}}), }, { //Locations - LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->ForestMedallion && logic->FireMedallion && logic->WaterMedallion), + 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->PocketEgg && logic->WakeUpAdultTalon), - LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->Slingshot || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslash)) && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon), + LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslash())) && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -29,32 +29,32 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAK_WINDMILL, {[]{return true;}}), Entrance(RR_KAK_BAZAAR, {[]{return logic->IsAdult && logic->AtDay;}}), Entrance(RR_KAK_SHOOTING_GALLERY, {[]{return logic->IsAdult && logic->AtDay;}}), - Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->DrainWell && (logic->IsChild || randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->DrainWell && (logic->IsChild || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}}), Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return logic->AtDay || logic->IsChild;}}), - Entrance(RR_KAK_REDEAD_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), - Entrance(RR_KAK_IMPAS_LEDGE, {[]{return (logic->IsChild && logic->AtDay) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && randoCtx->GetTrickOption(RT_VISIBLE_COLLISION));}}), - Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && (logic->IsAdult || logic->AtDay || logic->Slingshot || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)));}}), - Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (randoCtx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_KAK_REDEAD_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_KAK_IMPAS_LEDGE, {[]{return (logic->IsChild && logic->AtDay) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}}), + Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && (logic->IsAdult || logic->AtDay || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)));}}), + 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);}}), }); - areaTable[RR_KAK_IMPAS_LEDGE] = Area("Kak Impas Ledge", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_IMPAS_LEDGE] = Region("Kak Impas Ledge", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KAK_IMPAS_HOUSE_BACK, {[]{return true;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_IMPAS_ROOFTOP] = Area("Kak Impas Rooftop", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_IMPAS_ROOFTOP] = Region("Kak Impas Rooftop", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_KAK_GS_ABOVE_IMPAS_HOUSE, logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS && (logic->CanJumpslash || logic->CanUseProjectile)), + LOCATION(RC_KAK_GS_ABOVE_IMPAS_HOUSE, logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS() && (logic->CanJumpslash() || logic->CanUseProjectile())), }, { //Exits Entrance(RR_KAK_IMPAS_LEDGE, {[]{return true;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_ROOFTOP] = Area("Kak Rooftop", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_ROOFTOP] = Region("Kak Rooftop", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_MAN_ON_ROOF, true), }, { @@ -62,7 +62,7 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAK_BACKYARD, {[]{return true;}}), }); - areaTable[RR_KAK_BACKYARD] = Area("Kak Backyard", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_BACKYARD] = Region("Kak Backyard", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), Entrance(RR_KAK_OPEN_GROTTO, {[]{return true;}}), @@ -70,34 +70,34 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAK_POTION_SHOP_BACK, {[]{return logic->IsAdult && logic->AtDay;}}), }); - areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Area("Kak Carpenter Boss House", "Kak Carpenter Boss House", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", "Kak Carpenter Boss House", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->WakeUpAdultTalon, {[]{return logic->WakeUpAdultTalon || (logic->IsAdult && logic->PocketEgg);}}), + EventAccess(&logic->WakeUpAdultTalon, {[]{return logic->WakeUpAdultTalon || (logic->IsAdult && logic->CanUse(RG_POCKET_EGG));}}), }, {}, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Area("Kak House of Skulltula", "Kak House of Skulltula", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Region("Kak House of Skulltula", "Kak House of Skulltula", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_KAK_10_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 10), - LOCATION(RC_KAK_20_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 20), - LOCATION(RC_KAK_30_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 30), - LOCATION(RC_KAK_40_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 40), - LOCATION(RC_KAK_50_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 50), - LOCATION(RC_KAK_100_GOLD_SKULLTULA_REWARD, logic->GoldSkulltulaTokens >= 100) + LOCATION(RC_KAK_10_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 10), + LOCATION(RC_KAK_20_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 20), + LOCATION(RC_KAK_30_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 30), + LOCATION(RC_KAK_40_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 40), + LOCATION(RC_KAK_50_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 50), + LOCATION(RC_KAK_100_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 100) }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_IMPAS_HOUSE] = Area("Kak Impas House", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_IMPAS_HOUSE] = Region("Kak Impas House", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KAK_IMPAS_HOUSE_NEAR_COW, {[]{return true;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_IMPAS_HOUSE_BACK] = Area("Kak Impas House Back", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_IMPAS_HOUSE_BACK] = Region("Kak Impas House Back", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, true), }, { @@ -106,25 +106,25 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAK_IMPAS_HOUSE_NEAR_COW, {[]{return true;}}), }); - areaTable[RR_KAK_IMPAS_HOUSE_NEAR_COW] = Area("Kak Impas House Near Cow", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_IMPAS_HOUSE_NEAR_COW] = Region("Kak Impas House Near Cow", "Kak Impas House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)), }, {}); - areaTable[RR_KAK_WINDMILL] = Area("Kak Windmill", "Windmill and Dampes Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_KAK_WINDMILL] = Region("Kak Windmill", "Windmill and Dampes Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DrainWell, {[]{return logic->DrainWell || (logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && randoCtx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslash && randoCtx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), + LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslash() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), //PoH as child not added to trick options yet (needs uncommenting in randomizer_tricks.cpp) - LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->Ocarina), + LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_BAZAAR] = Area("Kak Bazaar", "Kak Bazaar", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", "Kak Bazaar", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_BAZAAR_ITEM_1, true), LOCATION(RC_KAK_BAZAAR_ITEM_2, true), @@ -139,15 +139,15 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_SHOOTING_GALLERY] = Area("Kak Shooting Gallery", "Kak Shooting Gallery", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_SHOOTING_GALLERY] = Region("Kak Shooting Gallery", "Kak Shooting Gallery", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->ChildsWallet && logic->IsAdult && logic->Bow), + LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_POTION_SHOP_FRONT] = Area("Kak Potion Shop Front", "Kak Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", "Kak Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult), LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult), @@ -163,30 +163,30 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAK_POTION_SHOP_BACK, {[]{return logic->IsAdult;}}), }); - areaTable[RR_KAK_POTION_SHOP_BACK] = Area("Kak Potion Shop Back", "Kak Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_POTION_SHOP_BACK] = Region("Kak Potion Shop Back", "Kak Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KAK_BACKYARD, {[]{return logic->IsAdult;}}), Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return true;}}), }); areaTable[RR_KAK_ODD_POTION_BUILDING] = - Area("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, { + Region("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events EventAccess(&logic->OddPoulticeAccess, { [] { - return logic->OddPoulticeAccess || (logic->IsAdult && (logic->OddMushroomAccess || (logic->OddMushroom && logic->DisableTradeRevert))); + return logic->OddPoulticeAccess || (logic->IsAdult && (logic->OddMushroomAccess || (logic->CanUse(RG_ODD_MUSHROOM) && logic->DisableTradeRevert))); } }), }, { - LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->OddMushroom), - LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && logic->OddMushroom && logic->AdultsWallet), + LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)), + LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM) && logic->HasItem(RG_ADULT_WALLET)), }, { // Exits Entrance(RR_KAK_BACKYARD, { [] { return true; } }), }); - areaTable[RR_KAK_REDEAD_GROTTO] = Area("Kak Redead Grotto", "Kak Redead Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_REDEAD_GROTTO_CHEST, logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), }, { @@ -194,41 +194,41 @@ void AreaTable_Init_Kakariko() { Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_OPEN_GROTTO] = Area("Kak Open Grotto", "Kak Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", "Kak Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), - LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_KAK_BACKYARD, {[]{return true;}}), }); - areaTable[RR_THE_GRAVEYARD] = Area("The Graveyard", "The Graveyard", RA_THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", RA_THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_THE_GRAVEYARD) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->ChildsWallet && logic->IsChild && logic->AtNight), //TODO: This needs to change - LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanPlantBugs && logic->CanChildAttack), + LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change + LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), Entrance(RR_GRAVEYARD_COMPOSERS_GRAVE, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), Entrance(RR_GRAVEYARD_HEART_PIECE_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), Entrance(RR_GRAVEYARD_DAMPES_GRAVE, {[]{return logic->IsAdult;}}), - Entrance(RR_GRAVEYARD_DAMPES_HOUSE, {[]{return logic->IsAdult || logic->AtDampeTime;}}), //TODO: This needs to be handled + Entrance(RR_GRAVEYARD_DAMPES_HOUSE, {[]{return logic->IsAdult /*|| logic->AtDampeTime*/;}}), //TODO: This needs to be handled in ToD rework Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return false;}}), }); - areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Area("Graveyard Shield Grave", "Graveyard Shield Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", "Graveyard Shield Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true), //Free Fairies @@ -237,7 +237,7 @@ void AreaTable_Init_Kakariko() { Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Area("Graveyard Heart Piece Grave", "Graveyard Heart Piece Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Region("Graveyard Heart Piece Grave", "Graveyard Heart Piece Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG)), }, { @@ -245,30 +245,30 @@ void AreaTable_Init_Kakariko() { Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[RR_GRAVEYARD_COMPOSERS_GRAVE] = Area("Graveyard Composers Grave", "Graveyard Composers Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_COMPOSERS_GRAVE] = Region("Graveyard Composers Grave", "Graveyard Composers Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource), - LOCATION(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, logic->CanUseProjectile || logic->CanJumpslash || logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource()), + LOCATION(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, logic->CanUseProjectile() || logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Area("Graveyard Dampes Grave", "Windmill and Dampes Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", "Windmill and Dampes Grave", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->DampesWindmillAccess, {[]{return logic->DampesWindmillAccess || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME));}}), }, { //Locations LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), - LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || randoCtx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), Entrance(RR_KAK_WINDMILL, {[]{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}}), }); - areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Area("Graveyard Dampes House", "Graveyard Dampes House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Region("Graveyard Dampes House", "Graveyard Dampes House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DAMPE_HINT, logic->IsAdult), }, { @@ -276,21 +276,21 @@ void AreaTable_Init_Kakariko() { Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Area("Graveyard Warp Pad Region", "Graveyard", RA_THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Region("Graveyard Warp Pad Region", "Graveyard", RA_THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_DINS_FIRE) || (randoCtx->GetTrickOption(RT_GY_SHADOW_FIRE_ARROWS) && logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS));}}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_GY_SHADOW_FIRE_ARROWS) && logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS));}}), }); - areaTable[RR_KAK_BEHIND_GATE] = Area("Kak Behind Gate", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_BEHIND_GATE] = Region("Kak Behind Gate", "Kakariko Village", RA_KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || randoCtx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->KakarikoVillageGateOpen || randoCtx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->KakarikoVillageGateOpen || ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}}), Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index 66c08590555..39316eea213 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp @@ -3,18 +3,18 @@ using namespace Rando; -void AreaTable_Init_LostWoods() { - areaTable[RR_KOKIRI_FOREST] = Area("Kokiri Forest", "Kokiri Forest", RA_KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { +void RegionTable_Init_LostWoods() { + areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", "Kokiri Forest", RA_KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_KOKIRI_FOREST) && logic->CanUse(RG_SONG_OF_STORMS));}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->KokiriSword && logic->DekuShield);}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), - LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanChildAttack && logic->AtNight && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS), - LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanPlantBugs && logic->CanChildAttack), - LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang || (randoCtx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS), + LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->AtNight && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), LOCATION(RC_KF_GOSSIP_STONE, true), }, { //Exits @@ -24,28 +24,28 @@ void AreaTable_Init_LostWoods() { 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("Big Skulltula") || logic->ForestTempleClear)) || randoCtx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), - Entrance(RR_LW_BRIDGE_FROM_FOREST, {[]{return logic->IsAdult || randoCtx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || logic->DekuTreeClear;}}), - Entrance(RR_KF_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), + Entrance(RR_LW_BRIDGE_FROM_FOREST, {[]{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || logic->DekuTreeClear;}}), + Entrance(RR_KF_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Area("KF Outside Deku Tree", "Kokiri Forest", RA_KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Region("KF Outside Deku Tree", "Kokiri Forest", RA_KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BOOMERANG))));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasExplosives || logic->CanUse(RG_DINS_FIRE))));}}), - EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->KokiriSword && logic->DekuShield);}}), + EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BOOMERANG))));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE))));}}), + EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true), LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (randoCtx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield));}}), - Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy("Big Skulltula") || logic->ForestTempleClear)) || randoCtx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || 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_FOREST_OPEN) || logic->ShowedMidoSwordAndShield));}}), + Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), }); - areaTable[RR_KF_LINKS_HOUSE] = Area("KF Link's House", "KF Link's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", "KF Link's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->LinksCow), }, { @@ -53,7 +53,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[RR_KF_MIDOS_HOUSE] = Area("KF Mido's House", "KF Mido's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_MIDOS_HOUSE] = Region("KF Mido's House", "KF Mido's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KF_MIDOS_TOP_LEFT_CHEST, true), LOCATION(RC_KF_MIDOS_TOP_RIGHT_CHEST, true), @@ -64,22 +64,22 @@ void AreaTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_SARIAS_HOUSE] = Area("KF Saria's House", "KF Saria's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_HOUSE_OF_TWINS] = Area("KF House of Twins", "KF House of Twins", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_HOUSE_OF_TWINS] = Region("KF House of Twins", "KF House of Twins", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_KNOW_IT_ALL_HOUSE] = Area("KF Know It All House", "KF Know It All House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_KNOW_IT_ALL_HOUSE] = Region("KF Know It All House", "KF Know It All House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_KOKIRI_SHOP] = Area("KF Kokiri Shop", "KF Kokiri Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_KOKIRI_SHOP] = Region("KF Kokiri Shop", "KF Kokiri Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KF_SHOP_ITEM_1, true), LOCATION(RC_KF_SHOP_ITEM_2, true), @@ -94,35 +94,35 @@ void AreaTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_STORMS_GROTTO] = Area("KF Storms Grotto", "KF Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", "KF Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), - LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[RR_LW_FOREST_EXIT] = Area("LW Forest Exit", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_LW_FOREST_EXIT] = Region("LW Forest Exit", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[RR_THE_LOST_WOODS] = Area("Lost Woods", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->OddMushroomAccess, {[]{return logic->OddMushroomAccess || (logic->IsAdult && (logic->CojiroAccess || logic->Cojiro));}}), + EventAccess(&logic->OddMushroomAccess, {[]{return logic->OddMushroomAccess || (logic->IsAdult && (logic->CojiroAccess || logic->CanUse(RG_COJIRO)));}}), EventAccess(&logic->PoachersSawAccess, {[]{return logic->PoachersSawAccess || (logic->IsAdult && logic->OddPoulticeAccess);}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}), - EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs;}}), + EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}), }, { //Locations LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), - LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->Cojiro), - LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->OddPoultice && logic->Cojiro), + LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), + LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION) && logic->CanUse(RG_COJIRO)), //all 5 buttons are logically required for memory game //because the chances of being able to beat it //every time you attempt it are as follows: @@ -131,52 +131,52 @@ void AreaTable_Init_LostWoods() { //3 buttons => 3.75% //4 buttons => 25.3125% //5 buttons => 100% - LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->Ocarina && logic->OcarinaButtons >= 5), + LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5), LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku), - LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanPlantBugs && logic->CanChildAttack), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_LW_GOSSIP_STONE, true), }, { //Exits Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), Entrance(RR_GC_WOODS_WARP, {[]{return true;}}), - Entrance(RR_LW_BRIDGE, {[]{return logic->CanLeaveForest && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || randoCtx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}), - Entrance(RR_ZORAS_RIVER, {[]{return logic->CanLeaveForest && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS));}}), - Entrance(RR_LW_BEYOND_MIDO, {[]{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || randoCtx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}}), - Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, {[]{return Here(RR_THE_LOST_WOODS, []{return logic->CanBlastOrSmash;});}}), + Entrance(RR_LW_BRIDGE, {[]{return logic->CanLeaveForest() && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_ZORAS_RIVER, {[]{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_LW_BEYOND_MIDO, {[]{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}}), + Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, {[]{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}}), }); - areaTable[RR_LW_BEYOND_MIDO] = Area("LW Beyond Mido", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), }, { //Locations - LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku), - LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku), - LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAdultAttack) || (randoCtx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS), - LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanPlantBugs && (logic->CanChildAttack || (randoCtx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->DekuShield))), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), + LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), }, { //Exits Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), Entrance(RR_THE_LOST_WOODS, {[]{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG);}}), Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), Entrance(RR_DEKU_THEATER, {[]{return true;}}), - Entrance(RR_LW_SCRUBS_GROTTO, {[]{return Here(RR_LW_BEYOND_MIDO, []{return logic->CanBlastOrSmash;});}}), + Entrance(RR_LW_SCRUBS_GROTTO, {[]{return Here(RR_LW_BEYOND_MIDO, []{return logic->BlastOrSmash();});}}), }); - areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Area("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), }); - areaTable[RR_DEKU_THEATER] = Area("Deku Theater", "Deku Theater", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_THEATER] = Region("Deku Theater", "Deku Theater", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->SkullMask), LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->MaskOfTruth), @@ -185,31 +185,31 @@ void AreaTable_Init_LostWoods() { Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), }); - areaTable[RR_LW_SCRUBS_GROTTO] = Area("LW Scrubs Grotto", "LW Scrubs Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LW_SCRUBS_GROTTO] = Region("LW Scrubs Grotto", "LW Scrubs Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_LW_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku), - LOCATION(RC_LW_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku), - LOCATION(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), }); - areaTable[RR_SFM_ENTRYWAY] = Area("SFM Entryway", "Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", "Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), - Entrance(RR_SACRED_FOREST_MEADOW, {[]{return logic->CanJumpslash || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER);}}), - Entrance(RR_SFM_WOLFOS_GROTTO, {[]{return logic->CanOpenBombGrotto;}}), + Entrance(RR_SACRED_FOREST_MEADOW, {[]{return logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_SFM_WOLFOS_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), }); - areaTable[RR_SACRED_FOREST_MEADOW] = Area("Sacred Forest Meadow", "Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", "Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->ZeldasLetter), + LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult), - LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true), LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true), LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true), @@ -218,10 +218,10 @@ void AreaTable_Init_LostWoods() { Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_HOOKSHOT);}}), Entrance(RR_SFM_FAIRY_GROTTO, {[]{return true;}}), - Entrance(RR_SFM_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), + Entrance(RR_SFM_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_SFM_FAIRY_GROTTO] = Area("SFM Fairy Grotto", "SFM Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", "SFM Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { @@ -229,25 +229,25 @@ void AreaTable_Init_LostWoods() { Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[RR_SFM_WOLFOS_GROTTO] = Area("SFM Wolfos Grotto", "SFM Wolfos Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", "SFM Wolfos Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->IsAdult || logic->Slingshot || logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), //RANDOTODO is this meant to auto-pass as adult? + LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->IsAdult || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), //RANDOTODO is this meant to auto-pass as adult? }, { //Exits Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), }); - areaTable[RR_SFM_STORMS_GROTTO] = Area("SFM Storms Grotto", "SFM Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SFM_STORMS_GROTTO] = Region("SFM Storms Grotto", "SFM Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku), - LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku), - LOCATION(RC_SFM_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_SFM_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[RR_LW_BRIDGE_FROM_FOREST] = Area("LW Bridge From Forest", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LW_BRIDGE_FROM_FOREST] = Region("LW Bridge From Forest", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_LW_GIFT_FROM_SARIA, true), }, { @@ -255,7 +255,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_LW_BRIDGE, {[]{return true;}}), }); - areaTable[RR_LW_BRIDGE] = Area("LW Bridge", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_LW_BRIDGE] = Region("LW Bridge", "Lost Woods", RA_THE_LOST_WOODS, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp index fb926506007..4f2435aec28 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp @@ -4,27 +4,27 @@ using namespace Rando; -void AreaTable_Init_ShadowTemple() { +void RegionTable_Init_ShadowTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Area("Shadow Temple Entryway", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEGINNING, {[]{return randoCtx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (randoCtx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), - Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return randoCtx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && (randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(SHADOW_TEMPLE)->IsVanilla()) { - areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Area("Shadow Temple Beginning", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla()) { + areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslash), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslash()), LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits @@ -32,122 +32,124 @@ void AreaTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), }); - areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Area("Shadow Temple First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), //This fairy pot is only on 3DS }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslash), + LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslash()), LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), }, { //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(RR_SHADOW_TEMPLE, 1, 2);}}), Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return false;}}), }); - areaTable[RR_SHADOW_TEMPLE_HUGE_PIT] = Area("Shadow Temple Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_HUGE_PIT] = Region("Shadow Temple Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslash), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslash), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslash()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot && (logic->Bombs || logic->GoronBracelet || (randoCtx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslash), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->Hookshot || (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->HoverBoots)), - LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot), + 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_GS_LIKE_LIKE_ROOM, logic->CanJumpslash()), + 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)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((randoCtx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && randoCtx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->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(RR_SHADOW_TEMPLE, 3, 4);}}), }); - areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Area("Shadow Temple Wind Tunnel", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return logic->CanJumpslash && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return logic->CanJumpslash() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}}), }); - areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Area("Shadow Temple Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslash), - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->CanAdultAttack), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslash()), + //RANDOTODO check if child can reach the token + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}}) + 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) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}) }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(SHADOW_TEMPLE)->IsMQ()) { - areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Area("Shadow Temple MQ Beginning", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ()) { + //RANDOTODO doublecheck CanAttack when rewriting, as I assumed it only checked adult due to the entrance + areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->HoverBoots || (randoCtx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT)));}}), - //Trick: logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->HoverBoots || (LogicShadowMQGap && logic->CanUse(RG_LONGSHOT))) - Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return logic->HasExplosives && logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT)));}}), + //Trick: logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (LogicShadowMQGap && logic->CanUse(RG_LONGSHOT))) + Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Area("Shadow Temple MQ Dead Hand Area", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Region("Shadow Temple MQ Dead Hand Region", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanJumpslash), - LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanJumpslash && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanJumpslash() && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, {}); - areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Area("Shadow Temple MQ First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAdultAttack || logic->CanUse(RG_NUTS)), - LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslash), - LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAdultAttack || logic->CanUse(RG_NUTS)), + LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), + LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), }, { //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(RR_SHADOW_TEMPLE, 2);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Area("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (randoCtx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (randoCtx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && randoCtx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return logic->HasFireSource || randoCtx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), - //Trick: logic->HasFireSource || LogicShadowMQHugePit + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return logic->HasFireSource() || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), + //Trick: logic->HasFireSource() || LogicShadowMQHugePit }); - areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Area("Shadow Temple MQ Lower Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->IsAdult && logic->CanUse(RG_LONGSHOT)), LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->HoverBoots) || logic->GoronBracelet), - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanJumpslash && logic->HoverBoots && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ) && randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HoverBoots && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && logic->Hookshot && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ) && - randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) && randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->Hookshot || (randoCtx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->HoverBoots)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanJumpslash() && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && + ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->HoverBoots && ((randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ) && randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->Hookshot && logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Area("Shadow Temple MQ Wind Tunnel", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash()), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, true), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, true), @@ -156,22 +158,22 @@ void AreaTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->Bow || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->Bow && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (randoCtx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_HOVER_BOOTS) && logic->BossKeyShadowTemple;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Area("Shadow Temple MQ Invisible Maze", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), //below previously returned true - LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, logic->CanUse(RG_LENS_OF_TRUTH) || randoCtx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)), LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), }, {}); } @@ -180,23 +182,23 @@ void AreaTable_Init_ShadowTemple() { | BOSS ROOM | ---------------------------*/ areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = - Area("Shadow Temple Boss Entryway", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Shadow Temple Boss Entryway", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, { [] { return randoCtx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false; } }), - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, { [] { return randoCtx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, { [] { return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, { [] { return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false; } }), Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = - Area("Shadow Temple Boss Room", "Shadow Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, + Region("Shadow Temple Boss Room", "Shadow Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events EventAccess(&logic->ShadowTempleClear, { [] { return logic->ShadowTempleClear || (logic->HasBossSoul(RG_BONGO_BONGO_SOUL) && - ((logic->CanUse(RG_LENS_OF_TRUTH) || randoCtx->GetTrickOption(RT_LENS_BONGO)) && + ((logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && - (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || randoCtx->GetTrickOption(RT_SHADOW_BONGO)))); + (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)))); } }), }, { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp index 747b5ec2f45..136ce864e5b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp @@ -4,141 +4,141 @@ using namespace Rando; -void AreaTable_Init_SpiritTemple() { +void RegionTable_Init_SpiritTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_SPIRIT_TEMPLE_ENTRYWAY] = Area("Spirit Temple Entryway", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SPIRIT_TEMPLE_ENTRYWAY] = Region("Spirit Temple Entryway", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla();}}), - Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsMQ();}}), + Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla();}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ();}}), Entrance(RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla()) { - areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Area("Spirit Temple Lobby", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla()) { + areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_SPIRIT_TEMPLE_CHILD, {[]{return logic->IsChild;}}), Entrance(RR_SPIRIT_TEMPLE_EARLY_ADULT, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[RR_SPIRIT_TEMPLE_CHILD] = Area("Child Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SPIRIT_TEMPLE_CHILD] = Region("Child Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutCrate, {[]{return true;}}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot)))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), - LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->Boomerang || logic->Slingshot || (logic->CanUse(RG_BOMBCHU_5) && randoCtx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives || ((logic->CanUse(RG_NUTS) || logic->Boomerang) && (logic->CanUse(RG_STICKS) || logic->KokiriSword || logic->Slingshot)))), + 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))))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_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)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (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))))), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), }); - areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Area("Child Spirit Temple Climb", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && 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, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && 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(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && 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, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && 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_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) || - (logic->CanTakeDamage && (logic->CanJumpslash || logic->HasProjectile(HasProjectileAge::Child))) || + (logic->TakeDamage() && (logic->CanJumpslash() || logic->HasProjectile(HasProjectileAge::Child))) || (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || - ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->CanTakeDamage && logic->CanJumpslash)))), + ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslash())))), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), }); - areaTable[RR_SPIRIT_TEMPLE_EARLY_ADULT] = Area("Early Adult Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_EARLY_ADULT] = Region("Early Adult Spirit Temple", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //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->Bombs && logic->IsAdult && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash)), + 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->CanJumpslash())), 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_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->Bow || logic->Hookshot || logic->CanUse(RG_BOMBCHU_5) || (logic->Bombs && randoCtx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), + 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)))), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), }); - areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Area("Spirit Temple Central Chamber", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Region("Spirit Temple Central Chamber", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && - (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->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) || (randoCtx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->Bow)) && logic->CanUse(RG_SILVER_GAUNTLETS))), + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (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, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && - (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->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) || (randoCtx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->Bow)) && logic->CanUse(RG_SILVER_GAUNTLETS))), + LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (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->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), - LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives && logic->Boomerang && logic->Hookshot) || - (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives) || - (logic->Hookshot && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && - logic->Boomerang && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))), + 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))), + 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, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && + logic->CanUse(RG_BOOMERANG) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))), - LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && randoCtx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill && randoCtx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && - randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->Boomerang && (logic->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) || - (randoCtx->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->Hookshot || logic->HoverBoots || randoCtx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), + LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + 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)))), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslash || logic->HasExplosives;}}), + Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslash() || 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_CHILD_CLIMB, {[]{return true;}}), }); - areaTable[RR_SPIRIT_TEMPLE_OUTDOOR_HANDS] = Area("Spirit Temple Outdoor Hands", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_OUTDOOR_HANDS] = Region("Spirit Temple Outdoor Hands", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->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(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()), }, { //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(RR_SPIRIT_TEMPLE, 5)) || (logic->CanUse(RG_SILVER_GAUNTLETS) && ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->HasExplosives()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)));}}), }); - areaTable[RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Central Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Central Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->MirrorShield || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives), - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives), - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives), + LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (randoCtx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->Bombs || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->Bow || logic->CanUse(RG_HOOKSHOT) || logic->Hammer)));}}), + 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))));}}), }); - areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->CanTakeDamage && randoCtx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->Bow && logic->Hookshot))), - LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->MirrorShield && logic->CanAdultAttack) || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + 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))), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return logic->MirrorShield && logic->HasExplosives && logic->Hookshot;}}), + Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT);}}), }); areaTable[RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] = - Area("Spirit Temple Inside Statue Head", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Spirit Temple Inside Statue Head", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, { [] { return true; } }), - Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->BossKeySpiritTemple; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsMQ()) { - areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Area("Spirit Temple MQ Lobby", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ()) { + areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations 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->CanBlastOrSmash;}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))), }, { //Exits @@ -147,89 +147,89 @@ void AreaTable_Init_SpiritTemple() { Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Area("Spirit Temple MQ Child", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Region("Spirit Temple MQ Child", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->KokiriSword && logic->CanUse(RG_BOMBCHU_5) && logic->Slingshot);}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT));}}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer;})), - LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->KokiriSword && logic->CanUse(RG_BOMBCHU_5) && logic->Slingshot && logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->KokiriSword || logic->Bombs), - LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))), - //Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Slingshot && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME))))) + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER);})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BOMB_BAG)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))), + //Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME))))) }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Area("Spirit Temple MQ Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Region("Spirit Temple MQ Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash || logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (randoCtx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && (logic->MirrorShield || (randoCtx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return logic->MirrorShield && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (randoCtx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE) && logic->Bow));}}), - //Trick: logic->MirrorShield && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQLowerAdult && logic->CanUse(RG_DINS_FIRE) && logic->Bow)) + Entrance(RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)));}}), + //Trick: logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQLowerAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))) Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}), - Entrance(RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->Hammer;}}), - Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash && (randoCtx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_SHARED] = Area("Spirit Temple MQ Shared", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_SHARED] = Region("Spirit Temple MQ Shared", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->Bow && logic->Slingshot)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult), + LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult), //Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult - LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, (randoCtx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->Boomerang && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT))) || logic->IsAdult), - //Trick: (LogicSpiritMQSunBlockGS && logic->Boomerang && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT)) || logic->IsAdult + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT))) || logic->IsAdult), + //Trick: (LogicSpiritMQSunBlockGS && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT)) || logic->IsAdult }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash && (randoCtx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)));}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)));}}), //Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH))) - Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || randoCtx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash && (randoCtx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}), //Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult) }); - areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Area("Spirit Temple MQ Lower Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Region("Spirit Temple MQ Lower Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG) + LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && 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)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Hammer), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG) + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && 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)), }, {}); - areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Region("Spirit Temple MQ Boss Region", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, randoCtx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->MirrorShield && logic->Hookshot;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = - Area("Spirit Temple MQ Inside Statue Head", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }), - Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->BossKeySpiritTemple; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Area("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), }, {}); - areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Area("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true), }, {}); @@ -238,16 +238,16 @@ void AreaTable_Init_SpiritTemple() { /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Area( + areaTable[RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Region( "Spirit Temple Boss Entryway", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, { [] { return randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false; } }), - Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, { [] { return randoCtx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, { [] { return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, { [] { return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false; } }), Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Area( + areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region( "Spirit Temple Boss Room", "Spirit Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp index ef9c5ecd9dd..3ed223db93f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp @@ -4,110 +4,110 @@ using namespace Rando; -void AreaTable_Init_WaterTemple() { +void RegionTable_Init_WaterTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[RR_WATER_TEMPLE_ENTRYWAY] = Area("Water Temple Entryway", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_ENTRYWAY] = Region("Water Temple Entryway", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->Swim && randoCtx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}), - Entrance(RR_WATER_TEMPLE_MQ_LOBBY, {[]{return logic->Swim && randoCtx->GetDungeon(WATER_TEMPLE)->IsMQ();}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}), + Entrance(RR_WATER_TEMPLE_MQ_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsMQ();}}), Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(WATER_TEMPLE)->IsVanilla()) { + if (ctx->GetDungeon(WATER_TEMPLE)->IsVanilla()) { //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] = Area("Water Temple Lobby", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_LOBBY] = Region("Water Temple Lobby", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return logic->WaterTempleLow || ((randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && randoCtx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}}), - Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->WaterTempleLow || ((randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), - Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->WaterTempleLow && logic->HasExplosives && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS)) && (randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), - Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return logic->WaterTempleLow && logic->GoronBracelet && (logic->IsChild || logic->CanDive || logic->CanUse(RG_IRON_BOOTS)) && (randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return logic->WaterTempleLow || ((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->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->WaterTempleLow && 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->WaterTempleLow && 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->WaterTempleLow && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW));}}), - Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer >= 16)) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}), Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, {[]{return logic->WaterTempleMiddle;}}), - Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (randoCtx->GetTrickOption(RT_DAMAGE_BOOST) && logic->Bombs && logic->CanTakeDamage));}}), - Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (randoCtx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->WaterTempleMiddle)));}}), + 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->WaterTempleLow || logic->WaterTempleMiddle) && (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->WaterTempleMiddle)));}}), Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->WaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return logic->WaterTempleHigh && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Area("Water Temple East Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->WaterTempleLow, {[]{return logic->WaterTempleLow || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, {}, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->WaterTempleLow || ((randoCtx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), Entrance(RR_WATER_TEMPLE_MAP_ROOM, {[]{return logic->WaterTempleHigh;}}), - Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->WaterTempleMiddle || (logic->WaterTempleHigh && logic->WaterTempleLow && ((logic->CanUse(RG_HOVER_BOOTS) && randoCtx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || randoCtx->GetTrickOption(RT_WATER_CRACKED_WALL)));}}), - Entrance(RR_WATER_TEMPLE_TORCH_ROOM, {[]{return logic->WaterTempleLow && (logic->HasFireSourceWithTorch || logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->WaterTempleMiddle || (logic->WaterTempleHigh && logic->WaterTempleLow && ((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->WaterTempleLow && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), }); - areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Area("Water Temple Map Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Region("Water Temple Map Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MAP_CHEST, (logic->MagicMeter && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MAP_CHEST, (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->MagicMeter && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Area("Water Temple Cracked Wall", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Region("Water Temple Cracked Wall", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->HasExplosives), + LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->HasExplosives()), }, { //Exits Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return true;}}), }); - areaTable[RR_WATER_TEMPLE_TORCH_ROOM] = Area("Water Temple Torch Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_TORCH_ROOM] = Region("Water Temple Torch Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, (logic->MagicMeter && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->MagicMeter && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_NORTH_LOWER] = Area("Water Temple North Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_NORTH_LOWER] = Region("Water Temple North Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return (logic->CanUse(RG_LONGSHOT) || (randoCtx->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(RR_WATER_TEMPLE, 4);}}), }); - areaTable[RR_WATER_TEMPLE_BOULDERS_LOWER] = Area("Water Temple Boulders Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_BOULDERS_LOWER] = Region("Water Temple Boulders Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //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) || 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_BLOCK_ROOM, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || randoCtx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP))) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_IRON_BOOTS));}}), + 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));}}), }); - areaTable[RR_WATER_TEMPLE_BLOCK_ROOM] = Area("Water Temple Block Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_BLOCK_ROOM] = Region("Water Temple Block Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return (logic->GoronBracelet && logic->HasExplosives) || logic->CanUse(RG_HOOKSHOT);}}), - Entrance(RR_WATER_TEMPLE_JETS_ROOM, {[]{return (logic->GoronBracelet && logic->HasExplosives) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return (logic->HasItem(RG_GORONS_BRACELET) && logic->HasExplosives()) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_JETS_ROOM, {[]{return (logic->HasItem(RG_GORONS_BRACELET) && logic->HasExplosives()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_HOVER_BOOTS));}}), }); - areaTable[RR_WATER_TEMPLE_JETS_ROOM] = Area("Water Temple Jets Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_JETS_ROOM] = Region("Water Temple Jets Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_BLOCK_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return true;}}), }); - areaTable[RR_WATER_TEMPLE_BOULDERS_UPPER] = Area("Water Temple Boulders Upper", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_BOULDERS_UPPER] = Region("Water Temple Boulders Upper", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //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 && randoCtx->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(RR_WATER_TEMPLE, 5);}}), }); - areaTable[RR_WATER_TEMPLE_BOSS_KEY_ROOM] = Area("Water Temple Boss Key Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_BOSS_KEY_ROOM] = Region("Water Temple Boss Key Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { @@ -115,74 +115,74 @@ void AreaTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && randoCtx->GetTrickOption(RT_WATER_BK_JUMP_DIVE)) || logic->IsChild || logic->CanDive) && 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(RR_WATER_TEMPLE, 5);}}), }); - areaTable[RR_WATER_TEMPLE_SOUTH_LOWER] = Area("Water Temple South Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_SOUTH_LOWER] = Region("Water Temple South Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_BEHIND_GATE, (logic->CanJumpslash || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_GS_BEHIND_GATE, (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[RR_WATER_TEMPLE_WEST_LOWER] = Area("Water Temple West Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_WEST_LOWER] = Region("Water Temple West Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->GoronBracelet;}}), - Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, {[]{return logic->CanJumpslash || logic->CanUseProjectile;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_GORONS_BRACELET);}}), + Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, {[]{return logic->CanJumpslash() || logic->CanUseProjectile();}}), }); - areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Area("Water Temple Dragon Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Region("Water Temple Dragon Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && randoCtx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) || - Here(RR_WATER_TEMPLE_RIVER, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((randoCtx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS))) || randoCtx->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))) || + 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));})), }, { //Exits Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return true;}}), }); - areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER] = Area("Water Temple Central Pillar Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER] = Region("Water Temple Central Pillar Lower", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return logic->CanUse(RG_HOOKSHOT);}}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->WaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer >= 40;}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->WaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}}), }); - areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Area("Water Temple Central Pillar Upper", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->WaterTempleMiddle, {[]{return logic->WaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((randoCtx->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))) || (randoCtx->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->WaterTempleHigh && 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(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->WaterTempleHigh && logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return true;}}), }); - areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT] = Area("Water Temple Central Pillar Basement", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT] = Region("Water Temple Central Pillar Basement", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer >= 40), + LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40), }, { //Exits - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer >= 16;}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}), }); - areaTable[RR_WATER_TEMPLE_EAST_MIDDLE] = Area("Water Temple East Middle", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_EAST_MIDDLE] = Region("Water Temple East Middle", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile), + LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile()), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[RR_WATER_TEMPLE_WEST_MIDDLE] = Area("Water Temple West Middle", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_WEST_MIDDLE] = Region("Water Temple West Middle", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->CanUseProjectile;}}), + Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->CanUseProjectile();}}), }); - areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Area("Water Temple High Water", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->WaterTempleHigh, {[]{return logic->WaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, {}, { @@ -190,36 +190,36 @@ void AreaTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), }); - areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Area("Water Temple Block Corridor", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Region("Water Temple Block Corridor", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->GoronBracelet && (logic->WaterTempleLow || logic->WaterTempleMiddle)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->WaterTempleLow || logic->WaterTempleMiddle)), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM] = Area("Water Temple Falling Platform Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM] = Region("Water Temple Falling Platform Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, logic->CanUse(RG_LONGSHOT) || (randoCtx->GetTrickOption(RT_WATER_RANG_FALLING_PLATFORM_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG)) || (randoCtx->GetTrickOption(RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))), + 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);}}), }); - areaTable[RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Area("Water Temple Dragon Pillars Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Region("Water Temple Dragon Pillars Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanUseProjectile;}}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanUseProjectile();}}), Entrance(RR_WATER_TEMPLE_DARK_LINK_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_DARK_LINK_ROOM] = Area("Water Temple Dark Link Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_DARK_LINK_ROOM] = Region("Water Temple Dark Link Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM, {[]{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD);}}), Entrance(RR_WATER_TEMPLE_LONGSHOT_ROOM, {[]{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD);}}), }); - areaTable[RR_WATER_TEMPLE_LONGSHOT_ROOM] = Area("Water Temple Longshot Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_LONGSHOT_ROOM] = Region("Water Temple Longshot Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, true), }, { @@ -228,75 +228,75 @@ void AreaTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_RIVER, {[]{return logic->IsChild || logic->CanUse(RG_SONG_OF_TIME);}}), }); - areaTable[RR_WATER_TEMPLE_RIVER] = Area("Water Temple River", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_RIVER] = Region("Water Temple River", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_WATER_TEMPLE_GS_RIVER, (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (randoCtx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_LONGSHOT))), + LOCATION(RC_WATER_TEMPLE_GS_RIVER, (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_LONGSHOT))), }, { //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));}}), }); - areaTable[RR_WATER_TEMPLE_PRE_BOSS_ROOM] = Area("Water Temple Pre Boss Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_PRE_BOSS_ROOM] = Region("Water Temple Pre Boss Room", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyWaterTemple;}}), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (randoCtx->GetDungeon(WATER_TEMPLE)->IsMQ()) { - areaTable[RR_WATER_TEMPLE_MQ_LOBBY] = Area("Water Temple MQ Lobby", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(WATER_TEMPLE)->IsMQ()) { + areaTable[RR_WATER_TEMPLE_MQ_LOBBY] = Region("Water Temple MQ Lobby", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_MQ_DIVE, {[]{return logic->IsAdult && logic->WaterTimer >= 24 && logic->CanUse(RG_IRON_BOOTS);}}), - Entrance(RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash && logic->Hearts > 0;}}), - Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyWaterTemple && logic->IsAdult && logic->CanJumpslash && logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_DIVE, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash();}}), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_MQ_DIVE] = Area("Water Temple MQ Dive", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_MQ_DIVE] = Region("Water Temple MQ Dive", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->HasFireSource && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((randoCtx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME)))), + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME)))), //Trick: logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((LogicWaterMQCentralPillar && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME))) }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), }); - areaTable[RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Area("Water Temple MQ Lowered Water Levels", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Region("Water Temple MQ Lowered Water Levels", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_WATER_TEMPLE_MQ_LOBBY, []{return logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasExplosives;})) && - (logic->CanJumpslash || logic->CanUseProjectile)), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_WATER_TEMPLE_MQ_LOBBY, []{return logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasExplosives();})) && + (logic->CanJumpslash() || logic->CanUseProjectile())), LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, logic->CanUse(RG_DINS_FIRE)), LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->IsAdult && logic->CanUse(RG_LONGSHOT)), }, {}); - areaTable[RR_WATER_TEMPLE_MQ_DARK_LINK_REGION] = Area("Water Temple MQ Dark Link Region", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_WATER_TEMPLE_MQ_DARK_LINK_REGION] = Region("Water Temple MQ Dark Link Region", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->IsAdult && logic->WaterTimer >= 24 && logic->CanUse(RG_DINS_FIRE) && (randoCtx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE) || logic->CanDive || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE) || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_WATER_TEMPLE_MQ_GS_RIVER, true), }, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return logic->IsAdult && logic->WaterTimer >= 24 && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS] = Area("Water Temple MQ Basement Gated Areas", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS] = Region("Water Temple MQ Basement Gated Areas", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->HoverBoots || logic->CanUse(RG_SCARECROW) || randoCtx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)), - LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanUse(RG_FIRE_ARROWS) && (logic->HoverBoots || logic->CanUse(RG_SCARECROW))), - LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, randoCtx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->HoverBoots || logic->CanUse(RG_SCARECROW) || randoCtx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && logic->CanJumpslash)), - //Trick: LogicWaterMQLockedGS || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->HoverBoots || logic->CanUse(RG_SCARECROW) || LogicWaterNorthBasementLedgeJump)) + LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)), + LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW))), + LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, ctx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && logic->CanJumpslash())), + //Trick: LogicWaterMQLockedGS || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || LogicWaterNorthBasementLedgeJump)) }, {}); } @@ -304,15 +304,15 @@ void AreaTable_Init_WaterTemple() { | BOSS ROOM | ---------------------------*/ areaTable[RR_WATER_TEMPLE_BOSS_ENTRYWAY] = - Area("Water Temple Boss Entryway", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + Region("Water Temple Boss Entryway", "Water Temple", RA_WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return randoCtx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false; } }), - Entrance(RR_WATER_TEMPLE_MQ_LOBBY, { [] { return randoCtx->GetDungeon(WATER_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_WATER_TEMPLE_MQ_LOBBY, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false; } }), Entrance(RR_WATER_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Area( + areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region( "Water Temple Boss Room", "Water Temple", RA_NONE, NO_DAY_NIGHT_CYCLE, { // Events diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp index 49a76414718..07a768fbd73 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp @@ -3,25 +3,25 @@ using namespace Rando; -void AreaTable_Init_ZorasDomain() { - areaTable[RR_ZR_FRONT] = Area("ZR Front", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, { +void RegionTable_Init_ZorasDomain() { + areaTable[RR_ZR_FRONT] = Region("ZR Front", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanChildAttack), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanAttack()), }, { //Exits - Entrance(RR_ZORAS_RIVER, {[]{return logic->IsAdult || logic->CanBlastOrSmash;}}), + Entrance(RR_ZORAS_RIVER, {[]{return logic->IsAdult || logic->BlastOrSmash();}}), Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_ZORAS_RIVER] = Area("Zora River", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), - EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs;}}), + EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}), }, { //Locations - LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->ChildsWallet && logic->IsChild), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && 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)), @@ -29,42 +29,42 @@ void AreaTable_Init_ZorasDomain() { LOCATION(RC_ZR_FROGS_SARIAS_SONG, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), LOCATION(RC_ZR_FROGS_SUNS_SONG, logic->IsChild && logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_ZR_FROGS_SONG_OF_TIME, logic->IsChild && logic->CanUse(RG_SONG_OF_TIME)), - LOCATION(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && randoCtx->GetTrickOption(RT_ZR_LOWER))), - LOCATION(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && randoCtx->GetTrickOption(RT_ZR_UPPER))), - LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->AtNight && logic->CanChildAttack && logic->CanGetNightTimeGS), - LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER))), + LOCATION(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_UPPER))), + LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->AtNight && logic->CanAttack() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), }, { //Exits Entrance(RR_ZR_FRONT, {[]{return true;}}), Entrance(RR_ZR_OPEN_GROTTO, {[]{return true;}}), - Entrance(RR_ZR_FAIRY_GROTTO, {[]{return Here(RR_ZORAS_RIVER, []{return logic->CanBlastOrSmash;});}}), - Entrance(RR_THE_LOST_WOODS, {[]{return logic->CanDive || logic->CanUse(RG_IRON_BOOTS);}}), - Entrance(RR_ZR_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), - Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (logic->IsChild && randoCtx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && randoCtx->GetTrickOption(RT_ZR_HOVERS));}}), + Entrance(RR_ZR_FAIRY_GROTTO, {[]{return Here(RR_ZORAS_RIVER, []{return logic->BlastOrSmash();});}}), + Entrance(RR_THE_LOST_WOODS, {[]{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_ZR_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), + Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));}}), }); - areaTable[RR_ZR_BEHIND_WATERFALL] = Area("ZR Behind Waterfall", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ZR_BEHIND_WATERFALL] = Region("ZR Behind Waterfall", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[RR_ZR_OPEN_GROTTO] = Area("ZR Open Grotto", "ZR Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_ZR_OPEN_GROTTO] = Region("ZR Open Grotto", "ZR Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), - LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle), + LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives), - LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives), + LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[RR_ZR_FAIRY_GROTTO] = Area("ZR Fairy Grotto", "ZR Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", "ZR Fairy Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Event EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { @@ -72,59 +72,59 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[RR_ZR_STORMS_GROTTO] = Area("ZR Storms Grotto", "ZR Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZR_STORMS_GROTTO] = Region("ZR Storms Grotto", "ZR Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku), - LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku), - LOCATION(RC_ZR_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_ZR_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[RR_ZORAS_DOMAIN] = Area("Zoras Domain", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_DOMAIN] = Region("Zoras Domain", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->EyeballFrogAccess, {[]{return logic->EyeballFrogAccess || (logic->IsAdult && logic->KingZoraThawed && (logic->Eyedrops || logic->EyeballFrog || logic->Prescription || logic->PrescriptionAccess));}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->EyeballFrogAccess, {[]{return logic->EyeballFrogAccess || (logic->IsAdult && logic->KingZoraThawed && (logic->CanUse(RG_EYEDROPS) || logic->CanUse(RG_EYEBALL_FROG) || logic->CanUse(RG_PRESCRIPTION) || logic->PrescriptionAccess));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), EventAccess(&logic->FishGroup, {[]{return logic->FishGroup || logic->IsChild;}}), - EventAccess(&logic->KingZoraThawed, {[]{return logic->KingZoraThawed || (logic->IsAdult && logic->BlueFire);}}), - EventAccess(&logic->DeliverLetter, {[]{return logic->DeliverLetter || (logic->RutosLetter && logic->IsChild && randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}}), + EventAccess(&logic->KingZoraThawed, {[]{return logic->KingZoraThawed || (logic->IsAdult && logic->BlueFire());}}), + EventAccess(&logic->DeliverLetter, {[]{return logic->DeliverLetter || (logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}}), }, { //Locations - LOCATION(RC_ZD_DIVING_MINIGAME, logic->Swim && logic->ChildsWallet && logic->IsChild), + 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->KingZoraThawed), - LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->KingZoraThawed && logic->Prescription), - LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->Bow || (logic->MagicMeter && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (randoCtx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslash)) && logic->CanGetNightTimeGS), - LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle), - LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle), - LOCATION(RC_ZD_FISH_3, logic->IsChild && logic->HasBottle), - LOCATION(RC_ZD_FISH_4, logic->IsChild && logic->HasBottle), - LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle), + LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), + LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && logic->AtNight && (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->CanJumpslash())) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_3, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_4, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_GOSSIP_STONE, true), - LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives), - LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return true;}}), - Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild && (logic->CanDive || logic->CanUse(RG_IRON_BOOTS));}}), - Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return logic->DeliverLetter || randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (randoCtx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}}), - Entrance(RR_ZD_SHOP, {[]{return logic->IsChild || logic->BlueFire;}}), - Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), + Entrance(RR_LAKE_HYLIA, {[]{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_SHOP, {[]{return logic->IsChild || logic->BlueFire();}}), + Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[RR_ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->CanBreakUpperBeehives), + LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(RR_ZORAS_DOMAIN, {[]{return logic->DeliverLetter || randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}}), + 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_FOUNTAIN, {[]{return true;}}), }); - areaTable[RR_ZD_SHOP] = Area("ZD Shop", "ZD Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZD_SHOP] = Region("ZD Shop", "ZD Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_ZD_SHOP_ITEM_1, true), LOCATION(RC_ZD_SHOP_ITEM_2, true), @@ -139,7 +139,7 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[RR_ZD_STORMS_GROTTO] = Area("ZD Storms Grotto", "ZD Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", "ZD Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { @@ -147,17 +147,17 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[RR_ZORAS_FOUNTAIN] = Area("Zoras Fountain", "Zoras Fountain", RA_ZORAS_FOUNTAIN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", RA_ZORAS_FOUNTAIN, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), }, { //Locations LOCATION(RC_ZF_ICEBERC_FREESTANDING_POH, logic->IsAdult), - LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->IronBoots && logic->WaterTimer >= 24), + LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), LOCATION(RC_ZF_GS_TREE, logic->IsChild), - LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS), - LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBlastOrSmash && logic->HookshotOrBoomerang && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), }, { @@ -165,10 +165,10 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}}), Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return logic->IsAdult;}}), - Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives;}}), + Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), }); - areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Area("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 76cf6f1bc90..ab064bfe00a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -10,6 +10,7 @@ #include "randomizer.hpp" #include "spoiler_log.hpp" #include "location_access.hpp" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include "../../randomizer/randomizerTypes.h" #include @@ -24,6 +25,8 @@ Rando::Option* currentSetting; bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, std::string seedInput) { const auto ctx = Rando::Context::GetInstance(); + ResetPerformanceTimers(); + StartPerformanceTimer(PT_WHOLE_SEED); srand(time(NULL)); // if a blank seed was entered, make a random one @@ -65,5 +68,27 @@ bool GenerateRandomizer(std::set excludedLocations, std::setGetOption(RSK_KEYSANITY).RestoreDelayedOption(); } + + StopPerformanceTimer(PT_WHOLE_SEED); + SPDLOG_DEBUG("Full Seed Genration Time: {}ms", GetPerformanceTimer(PT_WHOLE_SEED).count()); + SPDLOG_DEBUG("LogicReset time: {}ms", GetPerformanceTimer(PT_LOGIC_RESET).count()); + SPDLOG_DEBUG("Area->Reset time: {}ms", GetPerformanceTimer(PT_REGION_RESET).count()); + SPDLOG_DEBUG("Total Entrance Shuffle time: {}ms", GetPerformanceTimer(PT_ENTRANCE_SHUFFLE).count()); + SPDLOG_DEBUG("Total Shopsanity time: {}ms", GetPerformanceTimer(PT_SHOPSANITY).count()); + SPDLOG_DEBUG("Total Dungeon Specific Items time: {}ms", GetPerformanceTimer(PT_OWN_DUNGEON).count()); + SPDLOG_DEBUG("Total Misc Limited Checks time: {}ms", GetPerformanceTimer(PT_LIMITED_CHECKS).count()); + SPDLOG_DEBUG("Total Advancment Checks time: {}ms", GetPerformanceTimer(PT_ADVANCEMENT_ITEMS).count()); + SPDLOG_DEBUG("Total Other Checks time: {}ms", GetPerformanceTimer(PT_REMAINING_ITEMS).count()); + SPDLOG_DEBUG("Total Playthrough Generation time: {}ms", GetPerformanceTimer(PT_PLAYTHROUGH_GENERATION).count()); + SPDLOG_DEBUG("Total PareDownPlaythrough time: {}ms", GetPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH).count()); + SPDLOG_DEBUG("Total WotH generation time: {}ms", GetPerformanceTimer(PT_WOTH).count()); + SPDLOG_DEBUG("Total Foolish generation time: {}ms", GetPerformanceTimer(PT_FOOLISH).count()); + SPDLOG_DEBUG("Total Overrides time: {}ms", GetPerformanceTimer(PT_OVERRIDES).count()); + SPDLOG_DEBUG("Total Hint Generation time: {}ms", GetPerformanceTimer(PT_HINTS).count()); + SPDLOG_DEBUG("SpoilerLog writing time: {}ms", GetPerformanceTimer(PT_SPOILER_LOG).count()); + SPDLOG_DEBUG("Total Event Access Calculation time: {}ms", GetPerformanceTimer(PT_EVENT_ACCESS).count()); + SPDLOG_DEBUG("Total ToD Access Calculation: {}ms", GetPerformanceTimer(PT_TOD_ACCESS).count()); + SPDLOG_DEBUG("Total Entrance Logic Calculation time: {}ms", GetPerformanceTimer(PT_ENTRANCE_LOGIC).count()); + SPDLOG_DEBUG("Total Check Logic Calculation time: {}ms", GetPerformanceTimer(PT_LOCATION_LOGIC).count()); return true; } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index ef656120579..7ab3992667f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -11,6 +11,7 @@ #include "variables.h" #include "soh/OTRGlobals.h" #include "../option.h" +#include "soh/Enhancements/debugger/performanceTimer.h" namespace Playthrough { @@ -25,7 +26,9 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, ctx->ItemReset(); ctx->HintReset(); ctx->GetLogic()->Reset(); - Areas::AccessReset(); + StartPerformanceTimer(PT_REGION_RESET); + Regions::AccessReset(); + StopPerformanceTimer(PT_REGION_RESET); ctx->GetSettings()->FinalizeSettings(excludedLocations, enabledTricks); // once the settings have been finalized turn them into a string for hashing @@ -53,7 +56,6 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, Random_Init(finalHash); ctx->GetSettings()->SetHash(std::to_string(finalHash)); - ctx->GetLogic()->UpdateHelpers(); if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { VanillaFill(); // Just place items in their vanilla locations @@ -71,11 +73,13 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, //TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, etc.) // write logs SPDLOG_INFO("Writing Spoiler Log..."); + StartPerformanceTimer(PT_SPOILER_LOG); if (SpoilerLog_Write()) { SPDLOG_INFO("Writing Spoiler Log Done"); } else { SPDLOG_ERROR("Writing Spoiler Log Failed"); } + StopPerformanceTimer(PT_SPOILER_LOG); #ifdef ENABLE_DEBUG SPDLOG_INFO("Writing Placement Log..."); if (PlacementLog_Write()) { diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 509c6f8528c..d4d7ebdd7e5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -18,7 +18,6 @@ void RandoMain::GenerateRando(std::set excludedLocations, std:: Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); - CVarSave(); - CVarLoad(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); Rando::Context::GetInstance()->SetPlandoLoaded(false); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 6f785b505c1..001c62ced25 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -3,25 +3,23 @@ #include "random.hpp" #include "shops.hpp" +#include #include #include #include "z64item.h" - -std::vector NonShopItems = {}; +std::map NonShopItems = {}; static std::array, 0xF1> trickNameTable; // Table of trick names for ice traps bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet //Set vanilla shop item locations before potentially shuffling void PlaceVanillaShopItems() { - auto ctx = Rando::Context::GetInstance(); - //Loop to place vanilla items in each location - for (size_t i = 0; i < Rando::StaticData::shopLocationLists.size(); i++) { - for (size_t j = 0; j < Rando::StaticData::shopLocationLists[i].size(); j++) { - ctx->GetItemLocation(Rando::StaticData::shopLocationLists[i][j])->PlaceVanillaItem(); + auto ctx = Rando::Context::GetInstance(); + //Loop to place vanilla items in each location + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { + ctx->GetItemLocation(randomizerCheck)->PlaceVanillaItem(); } - } } //These are the vanilla shop items, but in a priority order of importance @@ -31,82 +29,85 @@ void PlaceVanillaShopItems() { //Shopsanity random will have anywhere from the first 32 to the first 56, so the order of items after 32 is relevant std::vector GetMinVanillaShopItems(int total_replaced) { std::vector minShopItems = { - RG_BUY_DEKU_SHIELD, - RG_BUY_HYLIAN_SHIELD, - RG_BUY_GORON_TUNIC, - RG_BUY_ZORA_TUNIC, - RG_BUY_DEKU_NUTS_5, - RG_BUY_DEKU_NUTS_5, - RG_BUY_DEKU_NUTS_10, - RG_BUY_DEKU_STICK_1, - RG_BUY_DEKU_STICK_1, - RG_BUY_DEKU_SEEDS_30, - RG_BUY_ARROWS_10, - RG_BUY_ARROWS_10, - RG_BUY_ARROWS_30, - RG_BUY_ARROWS_50, - RG_BUY_BOMBCHUS_10, - RG_BUY_BOMBCHUS_10, - RG_BUY_BOMBCHUS_10, - RG_BUY_BOMBCHUS_20, - RG_BUY_BOMBS_525, - RG_BUY_BOMBS_535, - RG_BUY_BOMBS_10, - RG_BUY_BOMBS_20, - RG_BUY_GREEN_POTION, - RG_BUY_RED_POTION_30, - RG_BUY_BLUE_FIRE, - RG_BUY_FAIRYS_SPIRIT, - RG_BUY_BOTTLE_BUG, - RG_BUY_FISH, - //^First 28 items from OoTR - RG_BUY_HYLIAN_SHIELD, - RG_BUY_BOTTLE_BUG, - RG_BUY_DEKU_STICK_1, - RG_BUY_FAIRYS_SPIRIT, - //^First 32 items: Always guaranteed - RG_BUY_BLUE_FIRE, - RG_BUY_FISH, - RG_BUY_BOMBCHUS_10, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_10, - RG_BUY_BOMBCHUS_20, - RG_BUY_BOMBS_535, - RG_BUY_RED_POTION_30, - //^First 40 items: Exist on shopsanity 3 or less - RG_BUY_BOMBS_30, - RG_BUY_BOMBCHUS_20, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_10, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_30, - RG_BUY_RED_POTION_40, - RG_BUY_FISH, - //^First 48 items: Exist on shopsanity 2 or less - RG_BUY_BOMBCHUS_20, - RG_BUY_ARROWS_30, - RG_BUY_RED_POTION_50, - RG_BUY_ARROWS_30, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_50, - RG_BUY_ARROWS_50, - RG_BUY_GREEN_POTION, - //^First 56 items: Exist on shopsanity 1 or less - RG_BUY_POE, - RG_BUY_POE, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - //^All 64 items: Only exist with shopsanity 0 - }; - //Now delete however many items there are to replace - for (int i = 0; i < total_replaced; i++) { - minShopItems.pop_back(); - } - return minShopItems; + RG_BUY_DEKU_SHIELD, + RG_BUY_HYLIAN_SHIELD, + RG_BUY_GORON_TUNIC, + RG_BUY_ZORA_TUNIC, + RG_BUY_DEKU_NUTS_5, + RG_BUY_BOMBS_20, + RG_BUY_BOMBCHUS_10, + RG_BUY_DEKU_STICK_1, + //^First 8 items: Exist on shopsanity 7 or less + RG_BUY_FAIRYS_SPIRIT, + RG_BUY_DEKU_SEEDS_30, + RG_BUY_ARROWS_10, + RG_BUY_BLUE_FIRE, + RG_BUY_RED_POTION_30, + RG_BUY_GREEN_POTION, + RG_BUY_DEKU_NUTS_10, + RG_BUY_BOMBCHUS_10, + //^First 16 items: Exist on shopsanity 6 or less + RG_BUY_BOMBCHUS_10, + RG_BUY_BOMBCHUS_20, + RG_BUY_BOMBS_525, + RG_BUY_BOMBS_535, + RG_BUY_BOMBS_10, + RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_30, + RG_BUY_ARROWS_50, + //^First 24 items: Exist on shopsanity 5 or less + RG_BUY_ARROWS_10, + RG_BUY_FAIRYS_SPIRIT, + RG_BUY_BOTTLE_BUG, + RG_BUY_FISH, + //^First 28 items from OoTR + RG_BUY_HYLIAN_SHIELD, + RG_BUY_BOTTLE_BUG, + RG_BUY_DEKU_STICK_1, + RG_BUY_DEKU_STICK_1, + //^First 32 items: Exist on shopsanity 4 or less + RG_BUY_BLUE_FIRE, + RG_BUY_FISH, + RG_BUY_BOMBCHUS_10, + RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_10, + RG_BUY_BOMBCHUS_20, + RG_BUY_BOMBS_535, + RG_BUY_RED_POTION_30, + //^First 40 items: Exist on shopsanity 3 or less + RG_BUY_BOMBS_30, + RG_BUY_BOMBCHUS_20, + RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_10, + RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_30, + RG_BUY_RED_POTION_40, + RG_BUY_FISH, + //^First 48 items: Exist on shopsanity 2 or less + RG_BUY_BOMBCHUS_20, + RG_BUY_ARROWS_30, + RG_BUY_RED_POTION_50, + RG_BUY_ARROWS_30, + RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_50, + RG_BUY_ARROWS_50, + RG_BUY_GREEN_POTION, + //^First 56 items: Exist on shopsanity 1 or less + RG_BUY_POE, + RG_BUY_POE, + RG_BUY_HEART, + RG_BUY_HEART, + RG_BUY_HEART, + RG_BUY_HEART, + RG_BUY_HEART, + RG_BUY_HEART, + //^All 64 items: Only exist with shopsanity 0 + }; + //Now delete however many items there are to replace + for (int i = 0; i < total_replaced; i++) { + minShopItems.pop_back(); + } + return minShopItems; } //This table contains a cumulative probability for each possible shop price based on @@ -117,12 +118,12 @@ std::vector GetMinVanillaShopItems(int total_replaced) { //Average price ~126 //~38% chance of needing no wallet, ~45% chance of needing 1, ~17% chance of needing 2 static constexpr std::array ShopPriceProbability= { - 0.005326994, 0.014908518, 0.027114719, 0.041315285, 0.057136304, 0.074325887, 0.092667151, 0.112002061, 0.132198214, 0.153125390, - 0.174696150, 0.196810540, 0.219388148, 0.242361379, 0.265657012, 0.289205134, 0.312970402, 0.336877590, 0.360881110, 0.384932772, - 0.408976198, 0.432982176, 0.456902494, 0.480686053, 0.504313389, 0.527746488, 0.550938554, 0.573856910, 0.596465330, 0.618736235, - 0.640646600, 0.662162782, 0.683240432, 0.703859801, 0.724001242, 0.743631336, 0.762722631, 0.781259986, 0.799198449, 0.816521905, - 0.833208595, 0.849243398, 0.864579161, 0.879211177, 0.893112051, 0.906263928, 0.918639420, 0.930222611, 0.940985829, 0.950914731, - 0.959992180, 0.968187000, 0.975495390, 0.981884488, 0.987344345, 0.991851853, 0.995389113, 0.997937921, 0.999481947, 1.000000000, + 0.005326994, 0.014908518, 0.027114719, 0.041315285, 0.057136304, 0.074325887, 0.092667151, 0.112002061, 0.132198214, 0.153125390, + 0.174696150, 0.196810540, 0.219388148, 0.242361379, 0.265657012, 0.289205134, 0.312970402, 0.336877590, 0.360881110, 0.384932772, + 0.408976198, 0.432982176, 0.456902494, 0.480686053, 0.504313389, 0.527746488, 0.550938554, 0.573856910, 0.596465330, 0.618736235, + 0.640646600, 0.662162782, 0.683240432, 0.703859801, 0.724001242, 0.743631336, 0.762722631, 0.781259986, 0.799198449, 0.816521905, + 0.833208595, 0.849243398, 0.864579161, 0.879211177, 0.893112051, 0.906263928, 0.918639420, 0.930222611, 0.940985829, 0.950914731, + 0.959992180, 0.968187000, 0.975495390, 0.981884488, 0.987344345, 0.991851853, 0.995389113, 0.997937921, 0.999481947, 1.000000000, }; // Generate random number from 5 to wallet max @@ -133,7 +134,7 @@ int GetPriceFromMax(int max) { // Get random price out of available "affordable prices", or just return 10 if Starter wallet is selected (no need to randomly select // from a single element) int GetPriceAffordable() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_STARTER)) { return 10; } @@ -148,7 +149,7 @@ int GetPriceAffordable() { } int GetRandomShopPrice() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); // If Shopsanity prices aren't Balanced, but Affordable is on, don't GetPriceFromMax if (ctx->GetOption(RSK_SHOPSANITY_PRICES_AFFORDABLE).Is(true) && ctx->GetOption(RSK_SHOPSANITY_PRICES).IsNot(RO_SHOPSANITY_PRICE_BALANCED)) { return GetPriceAffordable(); @@ -158,16 +159,13 @@ int GetRandomShopPrice() { int max = 0; // check settings for a wallet tier selection and set max amount as method for setting true randomization - if(ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_STARTER)) { + if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_STARTER)) { max = 19; // 95/5 - } - else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_ADULT)) { + } else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_ADULT)) { max = 40; // 200/5 - } - else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_GIANT)) { + } else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_GIANT)) { max = 100; // 500/5 - } - else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_TYCOON)) { + } else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_TYCOON)) { max = 199; // 995/5 } if (max != 0) { @@ -177,8 +175,8 @@ int GetRandomShopPrice() { int price = 150; // JUST in case something fails with the randomization, return sane price for balanced double random = RandomDouble(); //Randomly generated probability value for (size_t i = 0; i < ShopPriceProbability.size(); i++) { - if (random < ShopPriceProbability[i]) { //The randomly generated value has surpassed the total probability up to this point, so this is the generated price + if (random < ShopPriceProbability[i]) { price = i * 5; //i in range [0, 59], output in range [0, 295] in increments of 5 break; } @@ -190,8 +188,8 @@ int GetRandomShopPrice() { // multiplied by 20 instead of 60 to give values in rage [0, 95] in increments of 5 //Average price ~31 static constexpr std::array ScrubPriceProbability = { - 0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, 0.640029304, 0.697527584, 0.750024535, - 0.797518749, 0.840011707, 0.877508776, 0.910010904, 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000, + 0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, 0.640029304, 0.697527584, 0.750024535, + 0.797518749, 0.840011707, 0.877508776, 0.910010904, 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000, }; int16_t GetRandomScrubPrice() { @@ -204,748 +202,884 @@ int16_t GetRandomScrubPrice() { return -1; } -//Get 1 to 4, or a random number from 1-4 depending on shopsanity setting +//Get 0 to 7, or a random number from 1-7 depending on shopsanity setting int GetShopsanityReplaceAmount() { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_ONE_ITEM)) { - return 1; - } else if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_TWO_ITEMS)) { - return 2; - } else if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_THREE_ITEMS)) { - return 3; - } else if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_FOUR_ITEMS)) { - return 4; - } else { //Random, get number in [1, 4] - return Random(1, 5); - } + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { + return 0; + } else if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT)) { + if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS)) { + return 0; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ONE_ITEM)) { + return 1; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_TWO_ITEMS)) { + return 2; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_THREE_ITEMS)) { + return 3; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_FOUR_ITEMS)) { + return 4; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_FIVE_ITEMS)) { + return 5; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_SIX_ITEMS)) { + return 6; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_SEVEN_ITEMS)) { + return 7; + } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_EIGHT_ITEMS)) { + return 8; //temporarily unreachable due to logic limitations + } + } else { //Random, get number in [1, 7] + return Random(1, 8); + } } //Initialize the table of trick names with an easy, medium, and hard name for each language void InitTrickNames() { - trickNameTable[RG_KOKIRI_SWORD] = { - Text{"Korok Sword", "Épée Korok", "Espada Korok"}, - Text{"Hero's Sword", "Épée du Héros", "Espada del héroe"}, - Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}}; - trickNameTable[RG_MASTER_SWORD] = { //Master Sword without the GI enum - Text{"Goddess Sword", "Épée de la déesse", "Espada Divina"}, - Text{"Gilded Sword", "Excalibur", "Espada de los Sabios"}, - Text{"Magical Sword", "Lame dorée", "Fay"}}; - trickNameTable[RG_GIANTS_KNIFE] = { - Text{"Medigoron's Sword", "l'Épée de Medigoron", "La espada de Medigoron"}, - Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}, - Text{"Royal Claymore", "Claymore Royale", "Royal Claymore"}}; - trickNameTable[RG_BIGGORON_SWORD] = { - Text{"Power Sword", "Épée de Puissance", "Espada de poder"}, - Text{"Fierce Deity Sword", "Épée du dieu démon", "Espada de la Fiera Deidad"}, - Text{"Tempered Sword", "Épée de Légende Nv.2", "Espada Maestra mejorada"}, - Text{"Biggoron's Knife", "Lame de Grogoron", "Daga de Biggoron"}}; - trickNameTable[RG_DEKU_SHIELD] = { - Text{"Boko Shield", "Bouclier Boko", "Escudo Boko"}, - Text{"Ordon Shield", "Bouclier de Toal", "Escudo de Ordon"}, - Text{"Wooden Shield", "Bouclier de Bois", "Escudo de madera"}}; - trickNameTable[RG_HYLIAN_SHIELD] = { - Text{"Hyrule Shield", "Bouclier d'Hyrule", "Escudo Hylian"}, - Text{"Goddess Shield", "Bouclier Sacré", "Escudo Divino"}, - Text{"Hero's Shield", "Bouclier du Héros", "Escudo del héroe"}}; - trickNameTable[RG_MIRROR_SHIELD] = { - Text{"Magic Mirror", "Miroir Magique", "Escudo mágico"}, - Text{"Magical Shield", "Bouclier Magique", "Escudo arcano"}, - Text{"Mirror of Twilight", "Miroir des Ombres", "Espejo del Crepúsculo"}}; - trickNameTable[RG_GORON_TUNIC] = { - Text{"Gerudo Top", "Tunique Gerudo", "Pechera gerudo"}, - Text{"Flamebreaker Armor", "Armure de Pierre", " Armadura ignífuga"}, - Text{"Red Mail", "Habits Rouges", "Ropas rojas"}}; - trickNameTable[RG_ZORA_TUNIC] = { - Text{"Rito Tunic", "Tunique Rito", "Sayo rito"}, - Text{"Mermaid Suit", "Costume de sirène", "Costume de sirène"}, - Text{"Zora Armor", "Armure Zora", "Túnica Zora"}, - Text{"Blue Mail", "Habits Bleus", "Ropas azules"}}; - trickNameTable[RG_IRON_BOOTS] = { - Text{"Iron Hoofs", "Patins de Plomb", "Botas férreas"}, - Text{"Snow Boots", "Bottes de Neige", "Botas de nieve"}, - Text{"Red Boots", "Bottes rouges", "Botas rojas"}, - Text{"Zora Greaves", "Bottes Zora", "Zora Greaves"}, - Text{"Boots of Power", "Bottes de Puissance", "Botas de plomo"}}; - trickNameTable[RG_HOVER_BOOTS] = { - Text{"Hover Hoofs", "Patins des airs", "Botas flotadoras"}, - Text{"Golden Boots", "Bottes dorées", "Botas de Oro"}, - Text{"Pegasus Boots", "Bottes pégase", "Botas de Pegaso"}, - Text{"Boots of Speed", "Bottes de vitesse", "Botas del desierto"}}; - trickNameTable[RG_WEIRD_EGG] = { - Text{"Poached Egg", "Oeuf à la coque", "Huevo pasado"}, - Text{"Lon Lon Egg", "Oeuf Lon Lon", "Huevo Lon Lon"}, - Text{"Zora Egg", "Oeuf Zora", "Huevo Zora"}}; - trickNameTable[RG_ZELDAS_LETTER] = { + trickNameTable[RG_KOKIRI_SWORD] = { + Text{"Korok Sword", "Épée Korok", "Espada Korok"}, + Text{"Hero's Sword", "Épée du Héros", "Espada del héroe"}, + Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"} + }; + trickNameTable[RG_MASTER_SWORD] = { + Text{"Goddess Sword", "Épée de la déesse", "Espada Divina"}, + Text{"Gilded Sword", "Excalibur", "Espada de los Sabios"}, + Text{"Magical Sword", "Lame dorée", "Fay"} + }; + trickNameTable[RG_GIANTS_KNIFE] = { + Text{"Medigoron's Sword", "l'Épée de Medigoron", "La espada de Medigoron"}, + Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}, + Text{"Royal Claymore", "Claymore Royale", "Royal Claymore"} + }; + trickNameTable[RG_BIGGORON_SWORD] = { + Text{"Power Sword", "Épée de Puissance", "Espada de poder"}, + Text{"Fierce Deity Sword", "Épée du dieu démon", "Espada de la Fiera Deidad"}, + Text{"Tempered Sword", "Épée de Légende Nv.2", "Espada Maestra mejorada"}, + Text{"Biggoron's Knife", "Lame de Grogoron", "Daga de Biggoron"} + }; + trickNameTable[RG_DEKU_SHIELD] = { + Text{"Boko Shield", "Bouclier Boko", "Escudo Boko"}, + Text{"Ordon Shield", "Bouclier de Toal", "Escudo de Ordon"}, + Text{"Wooden Shield", "Bouclier de Bois", "Escudo de madera"} + }; + trickNameTable[RG_HYLIAN_SHIELD] = { + Text{"Hyrule Shield", "Bouclier d'Hyrule", "Escudo Hylian"}, + Text{"Goddess Shield", "Bouclier Sacré", "Escudo Divino"}, + Text{"Hero's Shield", "Bouclier du Héros", "Escudo del héroe"} + }; + trickNameTable[RG_MIRROR_SHIELD] = { + Text{"Magic Mirror", "Miroir Magique", "Escudo mágico"}, + Text{"Magical Shield", "Bouclier Magique", "Escudo arcano"}, + Text{"Mirror of Twilight", "Miroir des Ombres", "Espejo del Crepúsculo"} + }; + trickNameTable[RG_GORON_TUNIC] = { + Text{"Gerudo Top", "Tunique Gerudo", "Pechera gerudo"}, + Text{"Flamebreaker Armor", "Armure de Pierre", " Armadura ignífuga"}, + Text{"Red Mail", "Habits Rouges", "Ropas rojas"} + }; + trickNameTable[RG_ZORA_TUNIC] = { + Text{"Rito Tunic", "Tunique Rito", "Sayo rito"}, + Text{"Mermaid Suit", "Costume de sirène", "Costume de sirène"}, + Text{"Zora Armor", "Armure Zora", "Túnica Zora"}, + Text{"Blue Mail", "Habits Bleus", "Ropas azules"} + }; + trickNameTable[RG_IRON_BOOTS] = { + Text{"Iron Hoofs", "Patins de Plomb", "Botas férreas"}, + Text{"Snow Boots", "Bottes de Neige", "Botas de nieve"}, + Text{"Red Boots", "Bottes rouges", "Botas rojas"}, + Text{"Zora Greaves", "Bottes Zora", "Zora Greaves"}, + Text{"Boots of Power", "Bottes de Puissance", "Botas de plomo"} + }; + trickNameTable[RG_HOVER_BOOTS] = { + Text{"Hover Hoofs", "Patins des airs", "Botas flotadoras"}, + Text{"Golden Boots", "Bottes dorées", "Botas de Oro"}, + Text{"Pegasus Boots", "Bottes pégase", "Botas de Pegaso"}, + Text{"Boots of Speed", "Bottes de vitesse", "Botas del desierto"} + }; + trickNameTable[RG_WEIRD_EGG] = { + Text{"Poached Egg", "Oeuf à la coque", "Huevo pasado"}, + Text{"Lon Lon Egg", "Oeuf Lon Lon", "Huevo Lon Lon"}, + Text{"Zora Egg", "Oeuf Zora", "Huevo Zora"} + }; + trickNameTable[RG_ZELDAS_LETTER] = { Text{"Ruto's Letter", "Lettre de Ruto", "Carta de Ruto"}, - Text{"Royal Letter", "Lettre Eoyale", "Carta para Kafei"}, - Text{"Zelda's Business Card", "Carte d'affaires de Zelda", "Carta"}, - Text{"Letter to Kafei", "Lettre pour Kafei", "Carta para Kafei "}, - Text{"Goat's Letter", "Lettre de la Chèvre", "Carta de la Cabra"}, - Text{"Maggie's Letter", "Lettre de Maggy", "Carta de Dolores"}}; - trickNameTable[RG_BOOMERANG] = { - Text{"Banana", "Banane", "Plátano"}, - Text{"Prank Fetch Toy", "Inséparable Bâtonnet", "Bumerang"}, - Text{"Gale Boomerang", "Boomerang Tornade", "Bumerán tornado"}, - Text{"Magic Boomerang", "Boomerang Magique", "Bumerán mágico"}}; - trickNameTable[RG_LENS_OF_TRUTH] = { - Text{"Sheikah-leidoscope", "Sheikah-léidoscope", "Monóculo de la Verdad"}, - Text{"Sheikah Sensor", "Sonar Sheikah", "Sensor Sheikah"}, - Text{"Crystal of Vision", "Cristal de Vision", "Cristal de Visión"}, - Text{"Magnifying Lens", "Loupe", "Lente Aumentadora"}}; - trickNameTable[RG_MEGATON_HAMMER] = { - Text{"Goron Gavel", "Masse Perforatrice", "Mazo Goron"}, - Text{"Magic Hammer", "Marteau Magique", "Martillo mágico"}, - Text{"Skull Hammer", "Maillet Ressort", "Martillo de hierro"}}; - trickNameTable[RG_STONE_OF_AGONY] = { - Text{"Cave Charm", "Charme de grotte", "Amuleto de la cueva"}, - Text{"Stone of Agahnim", "Fragment d'Agahnim", "Piedra de Agahnim"}, - Text{"Shard of Agony", "Fragment de Souffrance", "Piedra de la Agonía"}, - Text{"Pirate's Charm", "Pierre de Pirate", "Amuleto Pirata"}}; - trickNameTable[RG_DINS_FIRE] = { - Text{"Eldin's Fire", "Feu d'Eldin", "Fuego de Eldin"}, - Text{"Din's Blaze", "Flamme de Din", "Poder de Din"}, - Text{"Magic Lantern", "Lanterne Magique", "Linterna mágica"}, - Text{"Ether Medallion", "Médaillon d'Éther", "Medallón de Tesoro"}, - Text{"Bombos Medallion", "Médaillon des Flammes", "Medallón del Temblor"}}; - trickNameTable[RG_FARORES_WIND] = { - Text{"Faron's Wind", "Vent de Firone", "Viento de Farone"}, - Text{"Farore's Windfall", "Zéphyr de Farore", "Valor de Farore"}, - Text{"Tingle Air", "Tingle Air", "Tingle de aire"}, - Text{"Travel Medallion", "Amulette de téléportation", "Medallón Maligno"}, - Text{"Irene's Taxi", "Le taxi d'Aëline", "El taxi de Airín"}}; - trickNameTable[RG_NAYRUS_LOVE] = { - Text{"Lanayru's Love", "Amour de Lanelle", "Amor de Lanayru"}, - Text{"Nayru's Passion", "Passion de Nayru", "Sabiduría de Nayru"}, - Text{"Tingle Shield", "Bouclier Tingle", "Escudo de hormigueo"}, - Text{"Shield Spell", "Bouclier Magique", "Hechizo de Protección"}, - Text{"Magic Armor", "Armure Magique", "Armadura mágica"}}; - trickNameTable[RG_FIRE_ARROWS] = { - Text{"Fire Rod", "Baguette de feu", "Cetro de fuego"}, - Text{"Bomb Arrow", "Flèche-Bombe", "Flecha bomba"}, - Text{"Red Candle", "Bougie Rouge", "Vela roja"}}; - trickNameTable[RG_ICE_ARROWS] = { - Text{"Ice Rod", "Baguette des Glaces", "Cetro de Hielo"}, - Text{"Ancient Arrow", "Flèche Archéonique", "Flecha ancestral"}, - Text{"Ice Trap Arrow", "Flèche de Piège de Glace", "Cetro de hielo"}}; - trickNameTable[RG_LIGHT_ARROWS] = { - Text{"Wind Arrow", "Flèche de Vent", "Flecha del Viento"}, - Text{"Wand of Gamelon", "Baguette de Gamelon", "Varita de Gamelón"}, - Text{"Shock Arrow", "Flèches Électriques", "Flecha eléctrica"}, - Text{"Silver Arrow", "Flèches d'Argent", "Flecha de plata"}}; - trickNameTable[RG_GERUDO_MEMBERSHIP_CARD] = { - Text{"Desert Title Deed", "Abonnement Gerudo", "Escritura del desierto"}, - Text{"Sickle Moon Flag", "Drapeau du croissant de lune", "Bandera de la Luna Creciente"}, - Text{"Complimentary ID", "Bon de félicitation", "Cupón especial"}, - Text{"Gerudo's Card", "Carte Goron", "Tóken Gerudo"}, - Text{"Gerudo's Membership Card", "Autographe de Nabooru", "Tarjeta Gerudo"}}; + Text{"Royal Letter", "Lettre Eoyale", "Carta para Kafei"}, + Text{"Zelda's Business Card", "Carte d'affaires de Zelda", "Carta"}, + Text{"Letter to Kafei", "Lettre pour Kafei", "Carta para Kafei "}, + Text{"Goat's Letter", "Lettre de la Chèvre", "Carta de la Cabra"}, + Text{"Maggie's Letter", "Lettre de Maggy", "Carta de Dolores"} + }; + trickNameTable[RG_BOOMERANG] = { + Text{"Banana", "Banane", "Plátano"}, + Text{"Prank Fetch Toy", "Inséparable Bâtonnet", "Bumerang"}, + Text{"Gale Boomerang", "Boomerang Tornade", "Bumerán tornado"}, + Text{"Magic Boomerang", "Boomerang Magique", "Bumerán mágico"} + }; + trickNameTable[RG_LENS_OF_TRUTH] = { + Text{"Sheikah-leidoscope", "Sheikah-léidoscope", "Monóculo de la Verdad"}, + Text{"Sheikah Sensor", "Sonar Sheikah", "Sensor Sheikah"}, + Text{"Crystal of Vision", "Cristal de Vision", "Cristal de Visión"}, + Text{"Magnifying Lens", "Loupe", "Lente Aumentadora"} + }; + trickNameTable[RG_MEGATON_HAMMER] = { + Text{"Goron Gavel", "Masse Perforatrice", "Mazo Goron"}, + Text{"Magic Hammer", "Marteau Magique", "Martillo mágico"}, + Text{"Skull Hammer", "Maillet Ressort", "Martillo de hierro"} + }; + trickNameTable[RG_STONE_OF_AGONY] = { + Text{"Cave Charm", "Charme de grotte", "Amuleto de la cueva"}, + Text{"Stone of Agahnim", "Fragment d'Agahnim", "Piedra de Agahnim"}, + Text{"Shard of Agony", "Fragment de Souffrance", "Piedra de la Agonía"}, + Text{"Pirate's Charm", "Pierre de Pirate", "Amuleto Pirata"} + }; + trickNameTable[RG_DINS_FIRE] = { + Text{"Eldin's Fire", "Feu d'Eldin", "Fuego de Eldin"}, + Text{"Din's Blaze", "Flamme de Din", "Poder de Din"}, + Text{"Magic Lantern", "Lanterne Magique", "Linterna mágica"}, + Text{"Ether Medallion", "Médaillon d'Éther", "Medallón de Tesoro"}, + Text{"Bombos Medallion", "Médaillon des Flammes", "Medallón del Temblor"} + }; + trickNameTable[RG_FARORES_WIND] = { + Text{"Faron's Wind", "Vent de Firone", "Viento de Farone"}, + Text{"Farore's Windfall", "Zéphyr de Farore", "Valor de Farore"}, + Text{"Tingle Air", "Tingle Air", "Tingle de aire"}, + Text{"Travel Medallion", "Amulette de téléportation", "Medallón Maligno"}, + Text{"Irene's Taxi", "Le taxi d'Aëline", "El taxi de Airín"} + }; + trickNameTable[RG_NAYRUS_LOVE] = { + Text{"Lanayru's Love", "Amour de Lanelle", "Amor de Lanayru"}, + Text{"Nayru's Passion", "Passion de Nayru", "Sabiduría de Nayru"}, + Text{"Tingle Shield", "Bouclier Tingle", "Escudo de hormigueo"}, + Text{"Shield Spell", "Bouclier Magique", "Hechizo de Protección"}, + Text{"Magic Armor", "Armure Magique", "Armadura mágica"} + }; + trickNameTable[RG_FIRE_ARROWS] = { + Text{"Fire Rod", "Baguette de feu", "Cetro de fuego"}, + Text{"Bomb Arrow", "Flèche-Bombe", "Flecha bomba"}, + Text{"Red Candle", "Bougie Rouge", "Vela roja"} + }; + trickNameTable[RG_ICE_ARROWS] = { + Text{"Ice Rod", "Baguette des Glaces", "Cetro de Hielo"}, + Text{"Ancient Arrow", "Flèche Archéonique", "Flecha ancestral"}, + Text{"Ice Trap Arrow", "Flèche de Piège de Glace", "Cetro de hielo"} + }; + trickNameTable[RG_LIGHT_ARROWS] = { + Text{"Wind Arrow", "Flèche de Vent", "Flecha del Viento"}, + Text{"Wand of Gamelon", "Baguette de Gamelon", "Varita de Gamelón"}, + Text{"Shock Arrow", "Flèches Électriques", "Flecha eléctrica"}, + Text{"Silver Arrow", "Flèches d'Argent", "Flecha de plata"} + }; + trickNameTable[RG_GERUDO_MEMBERSHIP_CARD] = { + Text{"Desert Title Deed", "Abonnement Gerudo", "Escritura del desierto"}, + Text{"Sickle Moon Flag", "Drapeau du croissant de lune", "Bandera de la Luna Creciente"}, + Text{"Complimentary ID", "Bon de félicitation", "Cupón especial"}, + Text{"Gerudo's Card", "Carte Goron", "Tóken Gerudo"}, + Text{"Gerudo's Membership Card", "Autographe de Nabooru", "Tarjeta Gerudo"} + }; - trickNameTable[RG_MAGIC_BEAN_PACK] = { - Text{"Funky Bean Pack", "Paquet de Fèves Magiques", "Lote de frijoles mágicos"}, - Text{"Grapple Berries", "Baies de grappin", "Bayas de garfio"}, - Text{"Crenel Bean Pack", "Paquet de Haricots Gonggle", "Lote de alubias mágicas"}, - Text{"Mystical Seed Pack", "Pack de graines mystiques", "Paquete de semillas místicas"}}; - trickNameTable[RG_DOUBLE_DEFENSE] = { - Text{"Diamond Hearts", "Coeurs de Diamant", "Contenedor de diamante"}, - Text{"Double Damage", "Double Souffrance", "Doble daño receptivo"}, - Text{"Quadruple Defence", "Quadruple Défence", "Defensa cuádruple"}}; + trickNameTable[RG_MAGIC_BEAN_PACK] = { + Text{"Funky Bean Pack", "Paquet de Fèves Magiques", "Lote de frijoles mágicos"}, + Text{"Grapple Berries", "Baies de grappin", "Bayas de garfio"}, + Text{"Crenel Bean Pack", "Paquet de Haricots Gonggle", "Lote de alubias mágicas"}, + Text{"Mystical Seed Pack", "Pack de graines mystiques", "Paquete de semillas místicas"} + }; + trickNameTable[RG_DOUBLE_DEFENSE] = { + Text{"Diamond Hearts", "Coeurs de Diamant", "Contenedor de diamante"}, + Text{"Double Damage", "Double Souffrance", "Doble daño receptivo"}, + Text{"Quadruple Defence", "Quadruple Défence", "Defensa cuádruple"} + }; - trickNameTable[RG_POCKET_EGG] = { - Text{"Arpagos Egg", "Oeuf d'Arpagos", "Huevo de Arpagos"}, - Text{"Lon Lon Egg", "oeuf Lon Lon", "Huevo Lon Lon"}, - Text{"Zora Egg", "oeuf Zora", "Huevo del Pez Viento"}}; - trickNameTable[RG_POCKET_EGG] = { - Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada portátil"}, - Text{"Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko"}, - Text{"Hatched Cucco", "Cocotte éclose", "Pollo de bolsillo"}}; - trickNameTable[RG_COJIRO] = { - Text{"Blucco", "Chair-Qui-Poule", "Cucazul"}, - Text{"Piyoko", "Piyoko", "Piyoko"}, - Text{"Dark Cucco", "Cocotte Sombre", "Cucco oscuro"}, - Text{"Grog's Cucco", "Cocotte de Grog", "Cuco de Grog"}}; - trickNameTable[RG_ODD_MUSHROOM] = { - Text{"Magic Mushroom", "Champignon magique", "Champiñón mágico"}, - Text{"Endura Shroom", "Champi Vigueur", "Champiñón del bosque"}, - Text{"Sleepy Toadstool", "Crapaud Fatigué", "Seta durmiente"}, - Text{"Mushroom", "Champignon", "Seta"}}; - trickNameTable[RG_ODD_POTION] = { - Text{"Odd Medicine", "Élixir suspect", "Poción rara"}, - Text{"Granny's Poultice", "Mixture de Granny", "Medicina de la abuela"}, - Text{"Mushroom Poultice", "Mixture de champignon", "Medicina de champiñones"}, - Text{"Secret Medicine", "Médicament", "Pócima secreta"}, - Text{"Mushroom Spores", "Spores de Champignons", "Esporas de hongos"}, - Text{"Hanyu Spore", "Hanyu Spore", "Espora Hanyu"}}; - trickNameTable[RG_POACHERS_SAW] = { - Text{"Carpenter's Saw", "Scie du charpentier", "Sierra del carpintero"}, - Text{"Poacher's Sword", "Hache du chasseur", "Espada del capataz"}, - Text{"Ancient Bladesaw", "Longue Épée Archéonique", "Mandoble ancestral"}, - Text{"Woodcutter's Axe", "Hache du Bûcheron", "Hacha de leñador"}, - Text{"Grog's Saw", "Scie de Grog", "Sierra del Cazador Furtivo"}}; - trickNameTable[RG_BROKEN_SWORD] = { - Text{"Broken Biggoron's Sword", "Épée brisée de Grogoron", "Espada de Biggoron rota"}, - Text{"Broken Giant's Knife", "Lame des Géants brisée", "Daga gigante rota"}, - Text{"Broken Noble Sword", "Épée noble brisée", "Espada noble rota"}, - Text{"Broken Picori Blade", "Épée Minish brisée", "Espada minish rota"}, - Text{"Decayed Master Sword", "Épée de légende pourrie", "Espada decadente de leyenda"}}; - trickNameTable[RG_PRESCRIPTION] = { - Text{"Biggoron's Prescription", "Ordonnance de Grogoron", "Receta de Biggoron"}, - Text{"Eyedrop Prescription", "Ordonnance de gouttes", "Receta ocular"}, - Text{"Urgent Prescription", "Ordonnance urgente", "Prescripción"}, - Text{"Swordsman's Scroll", "Précis d'escrime", "Esgrimidorium"}, - Text{"Portrait of Oren", "Portrait d'Orlène", "Retrato de Oren"}, - Text{"Letter to King Zora", "Lettre au roi Zora", "Carta al Rey Zora"}}; - trickNameTable[RG_EYEBALL_FROG] = { - Text{"Don Gero", "Don Gero", "Don Gero"}, - Text{"Hot-Footed Frog", "Grenouille à pieds chauds", "Rana de patas calientes"}, - Text{"Lost Swordsmith", "Forgeron perdu", "Espadachín perdido"}, - Text{"Eyedrop Frog", "Grenouille-qui-louche", "Globo Ocular de Rana"}}; - trickNameTable[RG_EYEDROPS] = { - Text{"Biggoron's Eyedrops", "Gouttes de Grogoron", "Gotas de Biggoron"}, - Text{"Hyrule's Finest Eyedrops", "Eau du Lac Hylia", "Gotas oculares"}, - Text{"Moon's Tear", "Larme de Lune", "Lágrima de Luna"}, - Text{"Engine Grease", "Graisse moteur", "Grasa del motor"}, - Text{"Zora Perfume", "Parfum Zora", "Perfume Zora"}}; - trickNameTable[RG_CLAIM_CHECK] = { - Text{"Clay Check", "Certificat Grogoron", "Comprobante de Reclamación"}, - Text{"Ancient Tablet", "Stèle ancienne", "Litografía arcana"}, - Text{"Sheikah Slate", "Tablette Sheikah", "Piedra Sheikah"}, - Text{"Cyclone Slate", "Ardoise des tornades", "Pizarra de los Torbellinos"}}; + trickNameTable[RG_POCKET_EGG] = { + Text{"Arpagos Egg", "Oeuf d'Arpagos", "Huevo de Arpagos"}, + Text{"Lon Lon Egg", "oeuf Lon Lon", "Huevo Lon Lon"}, + Text{"Zora Egg", "oeuf Zora", "Huevo del Pez Viento"} + }; + trickNameTable[RG_POCKET_EGG] = { + Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada portátil"}, + Text{"Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko"}, + Text{"Hatched Cucco", "Cocotte éclose", "Pollo de bolsillo"} + }; + trickNameTable[RG_COJIRO] = { + Text{"Blucco", "Chair-Qui-Poule", "Cucazul"}, + Text{"Piyoko", "Piyoko", "Piyoko"}, + Text{"Dark Cucco", "Cocotte Sombre", "Cucco oscuro"}, + Text{"Grog's Cucco", "Cocotte de Grog", "Cuco de Grog"} + }; + trickNameTable[RG_ODD_MUSHROOM] = { + Text{"Magic Mushroom", "Champignon magique", "Champiñón mágico"}, + Text{"Endura Shroom", "Champi Vigueur", "Champiñón del bosque"}, + Text{"Sleepy Toadstool", "Crapaud Fatigué", "Seta durmiente"}, + Text{"Mushroom", "Champignon", "Seta"} + }; + trickNameTable[RG_ODD_POTION] = { + Text{"Odd Medicine", "Élixir suspect", "Poción rara"}, + Text{"Granny's Poultice", "Mixture de Granny", "Medicina de la abuela"}, + Text{"Mushroom Poultice", "Mixture de champignon", "Medicina de champiñones"}, + Text{"Secret Medicine", "Médicament", "Pócima secreta"}, + Text{"Mushroom Spores", "Spores de Champignons", "Esporas de hongos"}, + Text{"Hanyu Spore", "Hanyu Spore", "Espora Hanyu"} + }; + trickNameTable[RG_POACHERS_SAW] = { + Text{"Carpenter's Saw", "Scie du charpentier", "Sierra del carpintero"}, + Text{"Poacher's Sword", "Hache du chasseur", "Espada del capataz"}, + Text{"Ancient Bladesaw", "Longue Épée Archéonique", "Mandoble ancestral"}, + Text{"Woodcutter's Axe", "Hache du Bûcheron", "Hacha de leñador"}, + Text{"Grog's Saw", "Scie de Grog", "Sierra del Cazador Furtivo"} + }; + trickNameTable[RG_BROKEN_SWORD] = { + Text{"Broken Biggoron's Sword", "Épée brisée de Grogoron", "Espada de Biggoron rota"}, + Text{"Broken Giant's Knife", "Lame des Géants brisée", "Daga gigante rota"}, + Text{"Broken Noble Sword", "Épée noble brisée", "Espada noble rota"}, + Text{"Broken Picori Blade", "Épée Minish brisée", "Espada minish rota"}, + Text{"Decayed Master Sword", "Épée de légende pourrie", "Espada decadente de leyenda"} + }; + trickNameTable[RG_PRESCRIPTION] = { + Text{"Biggoron's Prescription", "Ordonnance de Grogoron", "Receta de Biggoron"}, + Text{"Eyedrop Prescription", "Ordonnance de gouttes", "Receta ocular"}, + Text{"Urgent Prescription", "Ordonnance urgente", "Prescripción"}, + Text{"Swordsman's Scroll", "Précis d'escrime", "Esgrimidorium"}, + Text{"Portrait of Oren", "Portrait d'Orlène", "Retrato de Oren"}, + Text{"Letter to King Zora", "Lettre au roi Zora", "Carta al Rey Zora"} + }; + trickNameTable[RG_EYEBALL_FROG] = { + Text{"Don Gero", "Don Gero", "Don Gero"}, + Text{"Hot-Footed Frog", "Grenouille à pieds chauds", "Rana de patas calientes"}, + Text{"Lost Swordsmith", "Forgeron perdu", "Espadachín perdido"}, + Text{"Eyedrop Frog", "Grenouille-qui-louche", "Globo Ocular de Rana"} + }; + trickNameTable[RG_EYEDROPS] = { + Text{"Biggoron's Eyedrops", "Gouttes de Grogoron", "Gotas de Biggoron"}, + Text{"Hyrule's Finest Eyedrops", "Eau du Lac Hylia", "Gotas oculares"}, + Text{"Moon's Tear", "Larme de Lune", "Lágrima de Luna"}, + Text{"Engine Grease", "Graisse moteur", "Grasa del motor"}, + Text{"Zora Perfume", "Parfum Zora", "Perfume Zora"} + }; + trickNameTable[RG_CLAIM_CHECK] = { + Text{"Clay Check", "Certificat Grogoron", "Comprobante de Reclamación"}, + Text{"Ancient Tablet", "Stèle ancienne", "Litografía arcana"}, + Text{"Sheikah Slate", "Tablette Sheikah", "Piedra Sheikah"}, + Text{"Cyclone Slate", "Ardoise des tornades", "Pizarra de los Torbellinos"} + }; - trickNameTable[RG_GOLD_SKULLTULA_TOKEN] = { - Text{"Skulltula Token", "Bon de Skulltula dorée", "Símbolo de Skulltula"}, - Text{"Golden Skulltula Spirit", "Pièce de Skulltula dorée", "Tóken de Skulltula Dorada"}, - Text{"Gold Walltula Token", "Jeton de Walltula dorée", "Skulltula dorada"}, - Text{"Maiamai", "Ti'gorneau", "Maimai"}, - Text{"Gratitude Crystal", "Cristal de gratitude", "Gema de gratitud"}, - Text{"Korok Seed", "Noix korogu", "Semilla de kolog"}}; + trickNameTable[RG_GOLD_SKULLTULA_TOKEN] = { + Text{"Skulltula Token", "Bon de Skulltula dorée", "Símbolo de Skulltula"}, + Text{"Golden Skulltula Spirit", "Pièce de Skulltula dorée", "Tóken de Skulltula Dorada"}, + Text{"Gold Walltula Token", "Jeton de Walltula dorée", "Skulltula dorada"}, + Text{"Maiamai", "Ti'gorneau", "Maimai"}, + Text{"Gratitude Crystal", "Cristal de gratitude", "Gema de gratitud"}, + Text{"Korok Seed", "Noix korogu", "Semilla de kolog"} + }; - trickNameTable[RG_PROGRESSIVE_HOOKSHOT] = { - Text{"Progressive Grappling Hook", "Lance-chaîne (prog.)", "Garra progresiva"}, - Text{"Progressive Clawshot", "Grappin-griffe (prog.)", "Zarpa progresiva"}, - Text{"Progressive Gripshot", "Grappince (prog.)", "Enganchador progresivo"}, - Text{"Progressive Rope", "Corde (prog.)", "Cuerda progresivo"}}; - trickNameTable[RG_PROGRESSIVE_STRENGTH] = { - Text{"Power Glove", "Gant de Puissance (prog.)", "Guanteletes progresivos"}, - Text{"Power Bracelet", "Bracelet de Force (prog.)", "Brasaletes progresivos"}, - Text{"Magic Bracelet", "Bracelet Magique (prog.)", "Manoplas progresivas"}}; - trickNameTable[RG_PROGRESSIVE_BOMB_BAG] = { - Text{"Progressive Bomb Capacity", "Capacité de bombes (prog.)", "Mayor capacidad de bombas"}, - Text{"Progressive Bomb Pack", "Paquet de bombes (prog.)", "Zurrón de bombas progresivo"}, - Text{"Progressive Bomb Box", "Boîte à bombes (prog.)", "Bolsa de bombas progresiva"}, - Text{"Progressive Blast Mask", "Masque d'Explosion (prog.)", "Máscara explosiva progresiva"}, - Text{"Progressive Powder Kegs", "Baril de Poudre (prog.)", "Barril de polvo progresivo"}, - Text{"Progressive Remote Bombs", "Bombes à distance (prog.)", "Bombas remotas progresivas"}}; - trickNameTable[RG_PROGRESSIVE_BOW] = { - Text{"Progressive Arrow Capacity", "Capacité de flèches (prog.)", "Mayor capacidad de flechas"}, - Text{"Progressive Hero's Bow", "Arc du héros (prog.)", "Arco del héroe progresivo"}, - Text{"Progressive Arrow Holder", "Arbalète (prog.)", "Ballesta progresiva"}, - Text{"Progressive Crossbow", "Arbalète (prog.)", "Ballesta progresiva"}, - Text{"Progressive Sacred Bow", "Arc sacré (prog)", "Arco Sagrado Progresivo"}, - Text{"Progressive Lynel Bow", "Arc de Lynel (prog.)", "Arco de centaleón Progresivo"}}; - trickNameTable[RG_PROGRESSIVE_SLINGSHOT] = { - Text{"Progressive Seed Capacity", "Capacité de graines (prog.)", "Mayor capacidad de semillas"}, - Text{"Progressive Catapult", "Catapulte (prog.)", "Catapulta progresiva"}, - Text{"Progressive Scattershot", "Lance-Pierre rafale (prog.)", "Resortera múltiple progresiva"}, - Text{"Progressive Seed Launcher", "Lanceur de semences (prog.)", "Lanzador de semillas progresivo"}, - Text{"Progressive Seed Satchel", "Sac de graines (prog.)", "Bolsa de semillas progresiva"}}; - trickNameTable[RG_PROGRESSIVE_WALLET] = { - Text{"Progressive Rupee Capacity", "Capacité de rubis (prog.)", "Mayor capacidad de rupias"}, - Text{"Progressive Purse", "Sacoche (prog.)", "Cartera de rupias progresiva"}, - Text{"Progressive Rupee Bag", "Sac à rubis (prog.)", "Zurrón de rupias progresivo"}, - Text{"Progressive Rupoor Capacity", "Capacité de Roupir (prog.)", "Capacidad progresiva Rupobre"}, - Text{"Progressive Spoils Bag", "Sac à Butin (prog.)", "Bolsa de trofeos progresiva"}, - Text{"Progressive Ruby Bag", "Capacité du sac Ruby (prog.)", "Bolso Ruby progresivo"}}; - trickNameTable[RG_PROGRESSIVE_SCALE] = { - Text{"Progressive Flippers", "Palmes de Zora (prog.)", "Aletas de zora progresiva"}, - Text{"Progressive Dragon's Scale", "Écaille du dragon d'eau (prog.)", "Escama dragón acuático progresiva"}, - Text{"Progressive Diving Ability", "Plongée (prog.)", "Buceo progresivo"}, - Text{"Progressive Pearl", "Perle (prog.)", "Perla progresiva"}, - Text{"Progressive Scute", "Bulle (prog.)", "Fragmento Zora progresivo"}}; - trickNameTable[RG_PROGRESSIVE_NUT_UPGRADE] = { - Text{"Progressive Nut Pack", "Paquet de noix (prog.)", "Mayor capacidad de semillas"}, - Text{"Progressive Bait Bag", "Sac à Appâts (prog.)", "Bolsa de cebo progresiva"}, - Text{"Progressive Pear Capacity", "Capacité de poire (prog.)", "Capacidad progresiva de pera"}, - Text{"Progressive Nut Bag", "Sac de noix (prog.)", "Bolsa de nueces progresiva"}, - Text{"Progressive Husk Capacity", "Capacité de noisettes (prog.)", "Mayor capacidad de castañas"}}; - trickNameTable[RG_PROGRESSIVE_STICK_UPGRADE] = { - Text{"Progressive Stick Bag", "Sac de bâtons (prog.)", "Mayor capacidad de ramas deku"}, - Text{"Progressive Stick Pack", "Paquet de bâtons Mojo (prog.)", "Mayor capacidad de bastones"}, - Text{"Progressive Branch Capacity", "Capacité de la succursale (prog.)", "Capacidad progresiva de la sucursal"}, - Text{"Progressive Rod Capacity", "Capacité de tiges (prog.)", "Mayor capacidad de cetros deku"}}; - trickNameTable[RG_PROGRESSIVE_BOMBCHUS] = { - Text{"Progressive Bomblings", "Bombinsectes (prog.)", "Bombinsectos progresivos"}, - Text{"Progressive Sentrobe Bombs", "Bombe de Sphérodrone (prog.)", "Bomba de helicobot progresivo"}, - Text{"Progressive Bomb-ombs", "Bombe Soldat (prog.)", "Soldado bomba progresivo"}, - Text{"Progressive Missiles", "Missiles (prog.)", "Misiles progresivos"}, - Text{"Progressive Bombchu Bag", "Sac à Bombchu (prog.)", "Bombachus progresivos"}}; - trickNameTable[RG_PROGRESSIVE_MAGIC_METER] = { - Text{"Progressive Stamina Meter", "Jauge d'endurance (prog.)", "Medidor de vigor progresivo"}, - Text{"Progressive Energy Gauge", "Jauge d'énergie (prog.)", "Medidor de energía progresivo"}, - Text{"Progressive Magic Powder", "Poudre magique (prog.)", "Medidor de carga progresivo"}}; - trickNameTable[RG_PROGRESSIVE_OCARINA] = { - Text{"Progressive Memento", "Souvenir (prog.)", "Silbato progresivo"}, - Text{"Progressive Whistle", "Siffler (prog.)", "Silbido progresivo"}, - Text{"Progressive Flute", "Flûte (prog.)", "Flauta progresiva"}, - Text{"Progressive Recorder", "Harmonica (prog.)", "Armónica progresiva"}}; - trickNameTable[RG_PROGRESSIVE_GORONSWORD] = { - Text{"Progressive Titan Blade", "Lame des Titans (prog.)", "Hoja del Titán progresiva"}, - Text{"Progressive Goron Knife", "Lame Goron (prog.)", "Daga Goron progresiva"}, - Text{"Progressive Giant Sword", "Épée géante (prog.)", "Espada gigante progresiva"}, - Text{"Progressive Darknut Sword", "Épée de Darknut (prog.)", "Espada Darknut progresiva"}, - Text{"Progressive Power Sword", "Épée de Puissance (prog.)", "Espada de poder progresiva"}, - Text{"Progressive Big Stabby", "Gros coup de poignard (prog.)", "Gran puñalada progresiva"}}; + trickNameTable[RG_PROGRESSIVE_HOOKSHOT] = { + Text{"Progressive Grappling Hook", "Lance-chaîne (prog.)", "Garra progresiva"}, + Text{"Progressive Clawshot", "Grappin-griffe (prog.)", "Zarpa progresiva"}, + Text{"Progressive Gripshot", "Grappince (prog.)", "Enganchador progresivo"}, + Text{"Progressive Rope", "Corde (prog.)", "Cuerda progresivo"} + }; + trickNameTable[RG_PROGRESSIVE_STRENGTH] = { + Text{"Power Glove", "Gant de Puissance (prog.)", "Guanteletes progresivos"}, + Text{"Power Bracelet", "Bracelet de Force (prog.)", "Brasaletes progresivos"}, + Text{"Magic Bracelet", "Bracelet Magique (prog.)", "Manoplas progresivas"} + }; + trickNameTable[RG_PROGRESSIVE_BOMB_BAG] = { + Text{"Progressive Bomb Capacity", "Capacité de bombes (prog.)", "Mayor capacidad de bombas"}, + Text{"Progressive Bomb Pack", "Paquet de bombes (prog.)", "Zurrón de bombas progresivo"}, + Text{"Progressive Bomb Box", "Boîte à bombes (prog.)", "Bolsa de bombas progresiva"}, + Text{"Progressive Blast Mask", "Masque d'Explosion (prog.)", "Máscara explosiva progresiva"}, + Text{"Progressive Powder Kegs", "Baril de Poudre (prog.)", "Barril de polvo progresivo"}, + Text{"Progressive Remote Bombs", "Bombes à distance (prog.)", "Bombas remotas progresivas"} + }; + trickNameTable[RG_PROGRESSIVE_BOW] = { + Text{"Progressive Arrow Capacity", "Capacité de flèches (prog.)", "Mayor capacidad de flechas"}, + Text{"Progressive Hero's Bow", "Arc du héros (prog.)", "Arco del héroe progresivo"}, + Text{"Progressive Arrow Holder", "Arbalète (prog.)", "Ballesta progresiva"}, + Text{"Progressive Crossbow", "Arbalète (prog.)", "Ballesta progresiva"}, + Text{"Progressive Sacred Bow", "Arc sacré (prog)", "Arco Sagrado Progresivo"}, + Text{"Progressive Lynel Bow", "Arc de Lynel (prog.)", "Arco de centaleón Progresivo"} + }; + trickNameTable[RG_PROGRESSIVE_SLINGSHOT] = { + Text{"Progressive Seed Capacity", "Capacité de graines (prog.)", "Mayor capacidad de semillas"}, + Text{"Progressive Catapult", "Catapulte (prog.)", "Catapulta progresiva"}, + Text{"Progressive Scattershot", "Lance-Pierre rafale (prog.)", "Resortera múltiple progresiva"}, + Text{"Progressive Seed Launcher", "Lanceur de semences (prog.)", "Lanzador de semillas progresivo"}, + Text{"Progressive Seed Satchel", "Sac de graines (prog.)", "Bolsa de semillas progresiva"} + }; + trickNameTable[RG_PROGRESSIVE_WALLET] = { + Text{"Progressive Rupee Capacity", "Capacité de rubis (prog.)", "Mayor capacidad de rupias"}, + Text{"Progressive Purse", "Sacoche (prog.)", "Cartera de rupias progresiva"}, + Text{"Progressive Rupee Bag", "Sac à rubis (prog.)", "Zurrón de rupias progresivo"}, + Text{"Progressive Rupoor Capacity", "Capacité de Roupir (prog.)", "Capacidad progresiva Rupobre"}, + Text{"Progressive Spoils Bag", "Sac à Butin (prog.)", "Bolsa de trofeos progresiva"}, + Text{"Progressive Ruby Bag", "Capacité du sac Ruby (prog.)", "Bolso Ruby progresivo"} + }; + trickNameTable[RG_PROGRESSIVE_SCALE] = { + Text{"Progressive Flippers", "Palmes de Zora (prog.)", "Aletas de zora progresiva"}, + Text{"Progressive Dragon's Scale", "Écaille du dragon d'eau (prog.)", "Escama dragón acuático progresiva"}, + Text{"Progressive Diving Ability", "Plongée (prog.)", "Buceo progresivo"}, + Text{"Progressive Pearl", "Perle (prog.)", "Perla progresiva"}, + Text{"Progressive Scute", "Bulle (prog.)", "Fragmento Zora progresivo"} + }; + trickNameTable[RG_PROGRESSIVE_NUT_UPGRADE] = { + Text{"Progressive Nut Pack", "Paquet de noix (prog.)", "Mayor capacidad de semillas"}, + Text{"Progressive Bait Bag", "Sac à Appâts (prog.)", "Bolsa de cebo progresiva"}, + Text{"Progressive Pear Capacity", "Capacité de poire (prog.)", "Capacidad progresiva de pera"}, + Text{"Progressive Nut Bag", "Sac de noix (prog.)", "Bolsa de nueces progresiva"}, + Text{"Progressive Husk Capacity", "Capacité de noisettes (prog.)", "Mayor capacidad de castañas"} + }; + trickNameTable[RG_PROGRESSIVE_STICK_UPGRADE] = { + Text{"Progressive Stick Bag", "Sac de bâtons (prog.)", "Mayor capacidad de ramas deku"}, + Text{"Progressive Stick Pack", "Paquet de bâtons Mojo (prog.)", "Mayor capacidad de bastones"}, + Text{"Progressive Branch Capacity", "Capacité de la succursale (prog.)", "Capacidad progresiva de la sucursal"}, + Text{"Progressive Rod Capacity", "Capacité de tiges (prog.)", "Mayor capacidad de cetros deku"} + }; + trickNameTable[RG_PROGRESSIVE_BOMBCHUS] = { + Text{"Progressive Bomblings", "Bombinsectes (prog.)", "Bombinsectos progresivos"}, + Text{"Progressive Sentrobe Bombs", "Bombe de Sphérodrone (prog.)", "Bomba de helicobot progresivo"}, + Text{"Progressive Bomb-ombs", "Bombe Soldat (prog.)", "Soldado bomba progresivo"}, + Text{"Progressive Missiles", "Missiles (prog.)", "Misiles progresivos"}, + Text{"Progressive Bombchu Bag", "Sac à Bombchu (prog.)", "Bombachus progresivos"} + }; + trickNameTable[RG_PROGRESSIVE_MAGIC_METER] = { + Text{"Progressive Stamina Meter", "Jauge d'endurance (prog.)", "Medidor de vigor progresivo"}, + Text{"Progressive Energy Gauge", "Jauge d'énergie (prog.)", "Medidor de energía progresivo"}, + Text{"Progressive Magic Powder", "Poudre magique (prog.)", "Medidor de carga progresivo"} + }; + trickNameTable[RG_PROGRESSIVE_OCARINA] = { + Text{"Progressive Memento", "Souvenir (prog.)", "Silbato progresivo"}, + Text{"Progressive Whistle", "Siffler (prog.)", "Silbido progresivo"}, + Text{"Progressive Flute", "Flûte (prog.)", "Flauta progresiva"}, + Text{"Progressive Recorder", "Harmonica (prog.)", "Armónica progresiva"} + }; + trickNameTable[RG_PROGRESSIVE_GORONSWORD] = { + Text{"Progressive Titan Blade", "Lame des Titans (prog.)", "Hoja del Titán progresiva"}, + Text{"Progressive Goron Knife", "Lame Goron (prog.)", "Daga Goron progresiva"}, + Text{"Progressive Giant Sword", "Épée géante (prog.)", "Espada gigante progresiva"}, + Text{"Progressive Darknut Sword", "Épée de Darknut (prog.)", "Espada Darknut progresiva"}, + Text{"Progressive Power Sword", "Épée de Puissance (prog.)", "Espada de poder progresiva"}, + Text{"Progressive Big Stabby", "Gros coup de poignard (prog.)", "Gran puñalada progresiva"} + }; - trickNameTable[RG_EMPTY_BOTTLE] = { - Text{"Empty Canteen", "Cantine vide", "cantimplora vacía"}, - Text{"Vial of Winds", "Fiole de vents", "Vial de Vientos"}, - Text{"Tingle Bottle", "Flacon de Tingle", "Botella de Tingle"}, - Text{"Magic Bottle", "Flacon magique", "Frasco feérico"}, - Text{"Glass Bottle", "Flacon de verre", "Botella de cristal"}, - Text{"Bottle with Water", "Flacon d'eau", "Botella Tingle"}}; - trickNameTable[RG_BOTTLE_WITH_MILK] = { - Text{"Bottle with Chateau Romani", "Flacon de cuvée Romani", "Botella de Reserva Romani"}, - Text{"Bottle with Premium Milk", "Flacon avec lait de qualité supérieure", "Biberón con leche Premium"}, - Text{"Bottle with Mystery Milk", "Flacon de lait grand cru", "Botella de leche extra"}, - Text{"Bottle with Fresh Milk", "Flacon de lait frais", "Botella de leche fresca"},}; - trickNameTable[RG_BOTTLE_WITH_RED_POTION] = { - Text{"Bottle with Red Chu Jelly", "Flacon de gelée Chuchu rouge", "Jugo de Chuchu Rojo"}, - Text{"Bottle with Hibiscus Potion", "Flacon de potion de Hibiscus", "Botella de poción de Hibisco"}, - Text{"Bottle with Medicine of Life", "Flacon d'élixir rouge", "Botella de medicina de la vida"}, - Text{"Bottle with Heart Potion", "Flacon de potion de soin", "Botella de poción de salud"}}; - trickNameTable[RG_BOTTLE_WITH_GREEN_POTION] = { - Text{"Bottle with Green Chu Jelly", "Flacon de gelée Chuchu verte", "Jugo de Chuchu Verde"}, - Text{"Bottle with Lamp Oil", "Flacon de Huile à lanterne", "Botella de Aceite de candil "}, - Text{"Bottle with Medicine of Magic", "Flacon d'élixir vert", "Botella de medicina mágica"}, - Text{"Bottle with Stamina Potion", "Flacon d'Endurol", "Botella de elixir vigorizante"}}; - trickNameTable[RG_BOTTLE_WITH_BLUE_POTION] = { - Text{"Bottle with Blue Chu Jelly", "Flacon de gelée Chuchu bleue", "Jugo de Chuchu Azul"}, - Text{"Bottle with Water of Life", "Flacon d'élixir bleu", "Botella de agua de la vida"}, - Text{"Bottle with Air Potion", "Flacon de potion d'oxygène", "Botella de oxígeno"}}; - trickNameTable[RG_BOTTLE_WITH_FAIRY] = { - Text{"Bottle with Forest Firefly", "Flacon avec une luciole", "Luciérnaga del bosque"}, - Text{"Bottle with Deku Princess", "Flacon avec Deku Princess", "Botella con Deku Princess"}, - Text{"Bottle with Stray Fairy", "Flacon avec une fée perdue", "Hada perdida en una botella"}}; - trickNameTable[RG_BOTTLE_WITH_FISH] = { - Text{"Bottle with Small Jabu-Jabu", "Flacon avec mini Jabu-Jabu", "Lord Chapu-Chapu embotellado"}, - Text{"Bottle with Reekfish", "Flacon avec Reekfish", "Reekfish embotellada"}, - Text{"Bottle with Hyrule Bass", "Flacon avec perche d'Hyrule", "Locha de Hyrule embotellada"}, - Text{"Bottle with Hyrule Loach", "Flacon avec loche d'Hyrule", "Perca de Términa embotellada"}}; - trickNameTable[RG_BOTTLE_WITH_BLUE_FIRE] = { - Text{"Bottle with Will-O-Wisp", "Flacon avec feu follet", "Botella de llama azul"}, - Text{"Bottle with Ancient Flame", "Flacon de flamme ancienne", "Botella de fuego ancestral"}, - Text{"Bottle with a Blue Candle", "Flacon avec une bougie bleue", "Botella con una vela azul"}, - Text{"Bottle with Red Ice", "Flacon de Glace Rouge", "Botella de Hielo rojo"}, - Text{"Bottle with Nayru's Flame", "Flacon de flamme de Nayru", "Botella de llamas de Nayru"}}; - trickNameTable[RG_BOTTLE_WITH_BUGS] = { - Text{"Bottle with Baby Tektites", "Flacon de bébé Araknon", "Tektites en una botella"}, - Text{"Bottle with A Beetle", "Flacon avec un scarabée", "Botella con un escarabajo"}, - Text{"Bottle with Lanayru Ants", "Flacon de fourmis de Lanelle", "Celestarabajo embotellado"}, - Text{"Bottle with Insects", "Flacon de bibittes", "Saltabosques embotellados"}, - Text{"Bottle with a Golden Bee", "Flacon avec une abeille dorée", "Botella con una abeja dorada"}}; - trickNameTable[RG_BOTTLE_WITH_POE] = { - Text{"Bottle with Ghini", "Flacon avec Ghini", "Ghini en una botella"}, - Text{"Bottle with Reapling", "Flacon avec Âme Damnée", "Reapling en una botella"}, - Text{"Bottle with Imp Poe", "Flacon avec Spectre", "Espectro en una botella"}, - Text{"Bottle with Anti-Fairy", "Flacon avec Tetdoss", "Whisp en una botella"}}; + trickNameTable[RG_EMPTY_BOTTLE] = { + Text{"Empty Canteen", "Cantine vide", "cantimplora vacía"}, + Text{"Vial of Winds", "Fiole de vents", "Vial de Vientos"}, + Text{"Tingle Bottle", "Flacon de Tingle", "Botella de Tingle"}, + Text{"Magic Bottle", "Flacon magique", "Frasco feérico"}, + Text{"Glass Bottle", "Flacon de verre", "Botella de cristal"}, + Text{"Bottle with Water", "Flacon d'eau", "Botella Tingle"} + }; + trickNameTable[RG_BOTTLE_WITH_MILK] = { + Text{"Bottle with Chateau Romani", "Flacon de cuvée Romani", "Botella de Reserva Romani"}, + Text{"Bottle with Premium Milk", "Flacon avec lait de qualité supérieure", "Biberón con leche Premium"}, + Text{"Bottle with Mystery Milk", "Flacon de lait grand cru", "Botella de leche extra"}, + Text{"Bottle with Fresh Milk", "Flacon de lait frais", "Botella de leche fresca"},}; + trickNameTable[RG_BOTTLE_WITH_RED_POTION] = { + Text{"Bottle with Red Chu Jelly", "Flacon de gelée Chuchu rouge", "Jugo de Chuchu Rojo"}, + Text{"Bottle with Hibiscus Potion", "Flacon de potion de Hibiscus", "Botella de poción de Hibisco"}, + Text{"Bottle with Medicine of Life", "Flacon d'élixir rouge", "Botella de medicina de la vida"}, + Text{"Bottle with Heart Potion", "Flacon de potion de soin", "Botella de poción de salud"} + }; + trickNameTable[RG_BOTTLE_WITH_GREEN_POTION] = { + Text{"Bottle with Green Chu Jelly", "Flacon de gelée Chuchu verte", "Jugo de Chuchu Verde"}, + Text{"Bottle with Lamp Oil", "Flacon de Huile à lanterne", "Botella de Aceite de candil "}, + Text{"Bottle with Medicine of Magic", "Flacon d'élixir vert", "Botella de medicina mágica"}, + Text{"Bottle with Stamina Potion", "Flacon d'Endurol", "Botella de elixir vigorizante"} + }; + trickNameTable[RG_BOTTLE_WITH_BLUE_POTION] = { + Text{"Bottle with Blue Chu Jelly", "Flacon de gelée Chuchu bleue", "Jugo de Chuchu Azul"}, + Text{"Bottle with Water of Life", "Flacon d'élixir bleu", "Botella de agua de la vida"}, + Text{"Bottle with Air Potion", "Flacon de potion d'oxygène", "Botella de oxígeno"} + }; + trickNameTable[RG_BOTTLE_WITH_FAIRY] = { + Text{"Bottle with Forest Firefly", "Flacon avec une luciole", "Luciérnaga del bosque"}, + Text{"Bottle with Deku Princess", "Flacon avec Deku Princess", "Botella con Deku Princess"}, + Text{"Bottle with Stray Fairy", "Flacon avec une fée perdue", "Hada perdida en una botella"} + }; + trickNameTable[RG_BOTTLE_WITH_FISH] = { + Text{"Bottle with Small Jabu-Jabu", "Flacon avec mini Jabu-Jabu", "Lord Chapu-Chapu embotellado"}, + Text{"Bottle with Reekfish", "Flacon avec Reekfish", "Reekfish embotellada"}, + Text{"Bottle with Hyrule Bass", "Flacon avec perche d'Hyrule", "Locha de Hyrule embotellada"}, + Text{"Bottle with Hyrule Loach", "Flacon avec loche d'Hyrule", "Perca de Términa embotellada"} + }; + trickNameTable[RG_BOTTLE_WITH_BLUE_FIRE] = { + Text{"Bottle with Will-O-Wisp", "Flacon avec feu follet", "Botella de llama azul"}, + Text{"Bottle with Ancient Flame", "Flacon de flamme ancienne", "Botella de fuego ancestral"}, + Text{"Bottle with a Blue Candle", "Flacon avec une bougie bleue", "Botella con una vela azul"}, + Text{"Bottle with Red Ice", "Flacon de Glace Rouge", "Botella de Hielo rojo"}, + Text{"Bottle with Nayru's Flame", "Flacon de flamme de Nayru", "Botella de llamas de Nayru"} + }; + trickNameTable[RG_BOTTLE_WITH_BUGS] = { + Text{"Bottle with Baby Tektites", "Flacon de bébé Araknon", "Tektites en una botella"}, + Text{"Bottle with A Beetle", "Flacon avec un scarabée", "Botella con un escarabajo"}, + Text{"Bottle with Lanayru Ants", "Flacon de fourmis de Lanelle", "Celestarabajo embotellado"}, + Text{"Bottle with Insects", "Flacon de bibittes", "Saltabosques embotellados"}, + Text{"Bottle with a Golden Bee", "Flacon avec une abeille dorée", "Botella con una abeja dorada"} + }; + trickNameTable[RG_BOTTLE_WITH_POE] = { + Text{"Bottle with Ghini", "Flacon avec Ghini", "Ghini en una botella"}, + Text{"Bottle with Reapling", "Flacon avec Âme Damnée", "Reapling en una botella"}, + Text{"Bottle with Imp Poe", "Flacon avec Spectre", "Espectro en una botella"}, + Text{"Bottle with Anti-Fairy", "Flacon avec Tetdoss", "Whisp en una botella"} + }; - trickNameTable[RG_RUTOS_LETTER] = { - Text{"Bottle with Maggie's Letter", "Flacon avec lettre de Maggy", "Carta de Dolores"}, - Text{"Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei", "Carta para Kafei"}, - Text{"Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda", "Carta náutica"}}; - trickNameTable[RG_BOTTLE_WITH_BIG_POE] = { - Text{"Bottle with Composer Brother", "Flacon avec un compositeur", "Hermana Poe embotellada"}, - Text{"Bottle with Jalhalla", "Flacon avec Jalhalla", "Yaihalla embotellado"}, - Text{"Bottle with Grim Repoe", "Flacon avec le Faucheur", "Bubble en una botella"}}; + trickNameTable[RG_RUTOS_LETTER] = { + Text{"Bottle with Maggie's Letter", "Flacon avec lettre de Maggy", "Carta de Dolores"}, + Text{"Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei", "Carta para Kafei"}, + Text{"Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda", "Carta náutica"} + }; + trickNameTable[RG_BOTTLE_WITH_BIG_POE] = { + Text{"Bottle with Composer Brother", "Flacon avec un compositeur", "Hermana Poe embotellada"}, + Text{"Bottle with Jalhalla", "Flacon avec Jalhalla", "Yaihalla embotellado"}, + Text{"Bottle with Grim Repoe", "Flacon avec le Faucheur", "Bubble en una botella"} + }; - trickNameTable[RG_ZELDAS_LULLABY] = { - Text{"Ballad of the Goddess", "Chant de la déesse", "Cántico de la Diosa"}, - Text{"Song of Healing", "Chant de l'apaisement", "Canción de curación"}, - Text{"Song of the Hero", "Chant du héros", "Canción del héroe"}}; - trickNameTable[RG_EPONAS_SONG] = { - Text{"Song of Birds","Chant des oiseaux","Cantar del ave"}, - Text{"Song of Soaring", "Chant de l'envol", "Canción del viento"}, - Text{"Song of Horse", "Chant du cheval", "Chant du cheval"}}; - trickNameTable[RG_SARIAS_SONG] = { - Text{"Mido's Song", "La chanson de Mido", "La canción de Mido"}, - Text{"Kass' Theme", "Le thème de Kass", "El tema de Kass"}, - Text{"Tune of Echoes", "Chant des Échos ", "Melodía del Eco "}}; - trickNameTable[RG_SUNS_SONG] = { - Text{"Song of Passing", "Mambo de Manbo", "Melodía del transcurrir"}, - Text{"Command Melody", "Air du marionnettiste", "Cara al Sol"}, - Text{"Moon's Song", "La chanson de Moon", "La canción de la luna"}}; - trickNameTable[RG_SONG_OF_TIME] = { - Text{"Song of Double Time", "Chant accéléré", "Canción del doble tiempo"}, - Text{"Inverted Song of Time", "Chant du temps inversé", "Canción del tiempo invertida"}, - Text{"Tune of Ages", "Chant du Temps", "Melodía del Tiempo"}}; - trickNameTable[RG_SONG_OF_STORMS] = { - Text{"Ballad of Gales", "Requiem de la tornade", "Melodía del Tornado"}, - Text{"Frog's Song of Soul", "Rap des grenouilles", "Canción del alma de la rana"}, - Text{"Wind's Requiem", "Mélodie du vent", "Melodía del Viento"}}; - trickNameTable[RG_MINUET_OF_FOREST] = { - Text{"Saria's Karaoke", "Karaoké de Saria", "Dueto del bosque"}, - Text{"Sonata of Awakening", "Sonate de l'éveil", "Sonata del despertar"}, - Text{"Wind God's Aria", "Hymne du dieu du vent", "Melodía del Espíritu del Viento"}}; - trickNameTable[RG_BOLERO_OF_FIRE] = { - Text{"Darunia's Tango", "Tango de Darunia", "Coro del fuego"}, - Text{"Tune of Currents", "Chants des Flux", "Melodía de las Corrientes"}, - Text{"Goron Lullaby", "Berceuse des Gorons", "Nana goron"}}; - trickNameTable[RG_SERENADE_OF_WATER] = { - Text{"Ruto's Blues", "Blues de Ruto", "Sonata del agua"}, - Text{"New Wave Bossa Nova", "Bossa-nova des flots", "Bossanova de las olas"}, - Text{"Manbo's Mambo", "Mambo de Manbo", "Mambo de Manbo"}}; - trickNameTable[RG_REQUIEM_OF_SPIRIT] = { - Text{"Nabooru's Reggae", "Reggae de Nabooru", "Reggae del espíritu"}, - Text{"Elegy of Emptiness", "Hymne du vide", "Elegía al vacío"}, - Text{"Earth God's Lyric", "Hymne du dieu de la terre", "Melodía del Espíritu de la Tierra"}}; - trickNameTable[RG_NOCTURNE_OF_SHADOW] = { - Text{"Impa's Death Metal", "Death métal d'Impa", "Diurno de la sombra"}, - Text{"Oath to Order", "Ode de l'appel", "Oda al orden"}, - Text{"Song of Discovery", "Chant des secrets", "Canto revelador"}}; - trickNameTable[RG_PRELUDE_OF_LIGHT] = { - Text{"Rauru's Sing-Along", "Chansonnette de Rauru", "Predulio de luz"}, - Text{"Ballad of the Wind Fish", "Ballade sur Poisson-Rêve", "Balada del Piez Viento"}, - Text{"Song of Light", "Chant de la lumière", "Sonidos de la luz"}}; + trickNameTable[RG_ZELDAS_LULLABY] = { + Text{"Ballad of the Goddess", "Chant de la déesse", "Cántico de la Diosa"}, + Text{"Song of Healing", "Chant de l'apaisement", "Canción de curación"}, + Text{"Song of the Hero", "Chant du héros", "Canción del héroe"} + }; + trickNameTable[RG_EPONAS_SONG] = { + Text{"Song of Birds","Chant des oiseaux","Cantar del ave"}, + Text{"Song of Soaring", "Chant de l'envol", "Canción del viento"}, + Text{"Song of Horse", "Chant du cheval", "Chant du cheval"} + }; + trickNameTable[RG_SARIAS_SONG] = { + Text{"Mido's Song", "La chanson de Mido", "La canción de Mido"}, + Text{"Kass' Theme", "Le thème de Kass", "El tema de Kass"}, + Text{"Tune of Echoes", "Chant des Échos ", "Melodía del Eco "} + }; + trickNameTable[RG_SUNS_SONG] = { + Text{"Song of Passing", "Mambo de Manbo", "Melodía del transcurrir"}, + Text{"Command Melody", "Air du marionnettiste", "Cara al Sol"}, + Text{"Moon's Song", "La chanson de Moon", "La canción de la luna"} + }; + trickNameTable[RG_SONG_OF_TIME] = { + Text{"Song of Double Time", "Chant accéléré", "Canción del doble tiempo"}, + Text{"Inverted Song of Time", "Chant du temps inversé", "Canción del tiempo invertida"}, + Text{"Tune of Ages", "Chant du Temps", "Melodía del Tiempo"} + }; + trickNameTable[RG_SONG_OF_STORMS] = { + Text{"Ballad of Gales", "Requiem de la tornade", "Melodía del Tornado"}, + Text{"Frog's Song of Soul", "Rap des grenouilles", "Canción del alma de la rana"}, + Text{"Wind's Requiem", "Mélodie du vent", "Melodía del Viento"} + }; + trickNameTable[RG_MINUET_OF_FOREST] = { + Text{"Saria's Karaoke", "Karaoké de Saria", "Dueto del bosque"}, + Text{"Sonata of Awakening", "Sonate de l'éveil", "Sonata del despertar"}, + Text{"Wind God's Aria", "Hymne du dieu du vent", "Melodía del Espíritu del Viento"} + }; + trickNameTable[RG_BOLERO_OF_FIRE] = { + Text{"Darunia's Tango", "Tango de Darunia", "Coro del fuego"}, + Text{"Tune of Currents", "Chants des Flux", "Melodía de las Corrientes"}, + Text{"Goron Lullaby", "Berceuse des Gorons", "Nana goron"} + }; + trickNameTable[RG_SERENADE_OF_WATER] = { + Text{"Ruto's Blues", "Blues de Ruto", "Sonata del agua"}, + Text{"New Wave Bossa Nova", "Bossa-nova des flots", "Bossanova de las olas"}, + Text{"Manbo's Mambo", "Mambo de Manbo", "Mambo de Manbo"} + }; + trickNameTable[RG_REQUIEM_OF_SPIRIT] = { + Text{"Nabooru's Reggae", "Reggae de Nabooru", "Reggae del espíritu"}, + Text{"Elegy of Emptiness", "Hymne du vide", "Elegía al vacío"}, + Text{"Earth God's Lyric", "Hymne du dieu de la terre", "Melodía del Espíritu de la Tierra"} + }; + trickNameTable[RG_NOCTURNE_OF_SHADOW] = { + Text{"Impa's Death Metal", "Death métal d'Impa", "Diurno de la sombra"}, + Text{"Oath to Order", "Ode de l'appel", "Oda al orden"}, + Text{"Song of Discovery", "Chant des secrets", "Canto revelador"} + }; + trickNameTable[RG_PRELUDE_OF_LIGHT] = { + Text{"Rauru's Sing-Along", "Chansonnette de Rauru", "Predulio de luz"}, + Text{"Ballad of the Wind Fish", "Ballade sur Poisson-Rêve", "Balada del Piez Viento"}, + Text{"Song of Light", "Chant de la lumière", "Sonidos de la luz"} + }; - trickNameTable[RG_KOKIRI_EMERALD] = { - Text{"Pendant of Courage", "Pendentif du courage", "Colgante del valor"}, - Text{"Farore's Pearl", "Perle de Farore", "Orbe de Farore"}, - Text{"Aquanine", "Smaragdine", "Yerbánida"}, - Text{"Farore's Emerald", "Émeraude de Farore", "Esmeralda de Farore"}, - Text{"Kokiri's Peridot", "Péridot Kokiri", "Ágata de los Kokiri"}}; - trickNameTable[RG_GORON_RUBY] = { - Text{"Pendant of Power", "Pendentif de la force", "Colgante del poder"}, - Text{"Din's Pearl", "Perle de Din", "Orbe de Din"}, - Text{"Crimsonine", "Alzanine", "Bermellina"}, - Text{"Din's Ruby", "Rubis de Din", "Rubí de Din"}, - Text{"Goron's Garnet", "Grenat Goron", "Topacio de los Goron"}}; - trickNameTable[RG_ZORA_SAPPHIRE] = { - Text{"Pendant of Wisdom", "Pendentif de la sagesse", "Colgante de la sabiduría"}, - Text{"Nayru's Pearl", "Perle de Nayru", "Orbe de Nayru"}, - Text{"Azurine", "Aquanine", "Azurina"}, - Text{"Nayru's Sapphire", "Saphir de Nayru", "Zafiro de Nayru"}, - Text{"Zora's Aquamarine", "Aquamarine Zora", "Lapislázuli de los Zora"}}; - trickNameTable[RG_FOREST_MEDALLION] = { - Text{"Wind Medallion", "Médaillon du vent", "Medallón del Viento"}, - Text{"Wind Element", "Elément Vent", "Elemento de aire"}, - Text{"Saria's Medallion", "Médaillon de Saria", "Medallón de Saria"}, - Text{"Sign of Air", "Glyphe de l'air", "Glifo de aire"}, - Text{"Medallion of Forest", "Médaillon du Temple de la Forêt", "Medalla del Bosque"}}; - trickNameTable[RG_FIRE_MEDALLION] = { - Text{"Fire Element", "Elément Feu", "Elemento de fuego"}, - Text{"Darunia's Medallion", "Médaillon de Darunia", "Medallón de Darunia"}, - Text{"Sign of Fire", "Glyphe de feu", "Glifo de fuego"}, - Text{"Medallion of Fire", "Médaillon du Temple du Feu", "Medalla del Fuego"}}; - trickNameTable[RG_WATER_MEDALLION] = { - Text{"Water Element", "Elément Eau", "Elemento de agua"}, - Text{"Ice Medallion", "Médaillon de glace", "Medallón Helado"}, - Text{"Ruto's Medallion", "Médaillon de Ruto", "Medallón de Ruto"}, - Text{"Sign of Water", "Glyphe de l'eau", "Glifo de agua"}, - Text{"Medallion of Water", "Médaillon du Temple de l'Eau", "Medalla del Agua"}}; - trickNameTable[RG_SPIRIT_MEDALLION] = { - Text{"Earth Element", "Elément Terre", "Elemento de tierra"}, - Text{"Nabooru's Medallion", "Médaillon de Nabooru", "Medallón de Nabooru"}, - Text{"Sign of Earth", "Glyphe de la Terre", "Glifo de la tierra"}, - Text{"Medallion of Spirit", "Médaillon du Temple de l'Esprit", "Medalla del Espíritu"}}; - trickNameTable[RG_SHADOW_MEDALLION] = { - Text{"Fused Shadow", "Cristal d'ombre", "Sombra Fundida"}, - Text{"Impa's Medallion", "Médaillon d'Impa", "Medallón de Impa"}, - Text{"Sign of Illusion", "Glyphe de l'illusion", "Glifo de ilusión"}, - Text{"Medallion of Shadow", "Médaillon du Temple de l'Ombre", "Medalla de la Sombra"}}; - trickNameTable[RG_LIGHT_MEDALLION] = { - Text{"Compass of Light", "Boussole de lumière", "Brújula de Luz"}, - Text{"Rauru's Medallion", "Médaillon de Rauru", "Medallón de Rauru"}, - Text{"Sign of Destiny", "Glyphe du destin", "Glifo del destino"}, - Text{"Medallion of Light", "Médaillon du temple de lumière", "Medalla de la Luz"}}; + trickNameTable[RG_KOKIRI_EMERALD] = { + Text{"Pendant of Courage", "Pendentif du courage", "Colgante del valor"}, + Text{"Farore's Pearl", "Perle de Farore", "Orbe de Farore"}, + Text{"Aquanine", "Smaragdine", "Yerbánida"}, + Text{"Farore's Emerald", "Émeraude de Farore", "Esmeralda de Farore"}, + Text{"Kokiri's Peridot", "Péridot Kokiri", "Ágata de los Kokiri"} + }; + trickNameTable[RG_GORON_RUBY] = { + Text{"Pendant of Power", "Pendentif de la force", "Colgante del poder"}, + Text{"Din's Pearl", "Perle de Din", "Orbe de Din"}, + Text{"Crimsonine", "Alzanine", "Bermellina"}, + Text{"Din's Ruby", "Rubis de Din", "Rubí de Din"}, + Text{"Goron's Garnet", "Grenat Goron", "Topacio de los Goron"} + }; + trickNameTable[RG_ZORA_SAPPHIRE] = { + Text{"Pendant of Wisdom", "Pendentif de la sagesse", "Colgante de la sabiduría"}, + Text{"Nayru's Pearl", "Perle de Nayru", "Orbe de Nayru"}, + Text{"Azurine", "Aquanine", "Azurina"}, + Text{"Nayru's Sapphire", "Saphir de Nayru", "Zafiro de Nayru"}, + Text{"Zora's Aquamarine", "Aquamarine Zora", "Lapislázuli de los Zora"} + }; + trickNameTable[RG_FOREST_MEDALLION] = { + Text{"Wind Medallion", "Médaillon du vent", "Medallón del Viento"}, + Text{"Wind Element", "Elément Vent", "Elemento de aire"}, + Text{"Saria's Medallion", "Médaillon de Saria", "Medallón de Saria"}, + Text{"Sign of Air", "Glyphe de l'air", "Glifo de aire"}, + Text{"Medallion of Forest", "Médaillon du Temple de la Forêt", "Medalla del Bosque"} + }; + trickNameTable[RG_FIRE_MEDALLION] = { + Text{"Fire Element", "Elément Feu", "Elemento de fuego"}, + Text{"Darunia's Medallion", "Médaillon de Darunia", "Medallón de Darunia"}, + Text{"Sign of Fire", "Glyphe de feu", "Glifo de fuego"}, + Text{"Medallion of Fire", "Médaillon du Temple du Feu", "Medalla del Fuego"} + }; + trickNameTable[RG_WATER_MEDALLION] = { + Text{"Water Element", "Elément Eau", "Elemento de agua"}, + Text{"Ice Medallion", "Médaillon de glace", "Medallón Helado"}, + Text{"Ruto's Medallion", "Médaillon de Ruto", "Medallón de Ruto"}, + Text{"Sign of Water", "Glyphe de l'eau", "Glifo de agua"}, + Text{"Medallion of Water", "Médaillon du Temple de l'Eau", "Medalla del Agua"} + }; + trickNameTable[RG_SPIRIT_MEDALLION] = { + Text{"Earth Element", "Elément Terre", "Elemento de tierra"}, + Text{"Nabooru's Medallion", "Médaillon de Nabooru", "Medallón de Nabooru"}, + Text{"Sign of Earth", "Glyphe de la Terre", "Glifo de la tierra"}, + Text{"Medallion of Spirit", "Médaillon du Temple de l'Esprit", "Medalla del Espíritu"} + }; + trickNameTable[RG_SHADOW_MEDALLION] = { + Text{"Fused Shadow", "Cristal d'ombre", "Sombra Fundida"}, + Text{"Impa's Medallion", "Médaillon d'Impa", "Medallón de Impa"}, + Text{"Sign of Illusion", "Glyphe de l'illusion", "Glifo de ilusión"}, + Text{"Medallion of Shadow", "Médaillon du Temple de l'Ombre", "Medalla de la Sombra"} + }; + trickNameTable[RG_LIGHT_MEDALLION] = { + Text{"Compass of Light", "Boussole de lumière", "Brújula de Luz"}, + Text{"Rauru's Medallion", "Médaillon de Rauru", "Medallón de Rauru"}, + Text{"Sign of Destiny", "Glyphe du destin", "Glifo del destino"}, + Text{"Medallion of Light", "Médaillon du temple de lumière", "Medalla de la Luz"} + }; - trickNameTable[RG_RECOVERY_HEART] = { - Text{"Love", "Bisou", "Te amo"}, - Text{"Life", "Vie", "vida"}, - Text{"HP", "VP", "VP"}}; - trickNameTable[RG_GREEN_RUPEE] = { - Text{"False Greg", "Faux Greg", "Falso Greg"}, - Text{"One Ruby", "Un rubis", "Un rubí"}, - Text{"Rupoor (1)", "Roupir (1)", "Rupobre (1)"}, - Text{"One Rupee", "Un rubis", "Guaraní hyliano"}, - Text{"Rupee (1)", "Rubis (1)", "Peso hyliano"}}; - trickNameTable[RG_BLUE_RUPEE] = { - Text{"Blupee", "Bleubi", "Azupia"}, - Text{"Five Rubies", "Cinq Rubys", "Cinco rubíes"}, - Text{"Five Rupees", "Cinq rubis", "Bolívar hyliano"}, - Text{"Rupee (5)", "Rubis (5)", "Peso hyliano"}, - Text{"Rupoor (5)", "Roupir (5)", "Rupobre (5)"}}; - trickNameTable[RG_RED_RUPEE] = { - Text{"Big 20", "Grand 20", "Los 20 grandes"}, - Text{"Twenty Rubies", "vingt rubis", "Veinte rubíes"}, - Text{"Rupoor (20)", "Roupir (20)", "Rupobre (20)"}, - Text{"Twenty Rupees", "Vingt rubis", "Colon hyliano"}, - Text{"Rupee (20)", "Rubis (20)", "Peso hyliano"}}; - trickNameTable[RG_PURPLE_RUPEE] = { - Text{"Purpee", "pourbi", "morupiua"}, - Text{"Fifty Rubies", "cinquante rubis", "Cincuenta rubíes"}, - Text{"Rupoor (50)", "Roupir (50)", "Rupobre (50)"}, - Text{"Fifty Rupees", "Cinquante rubis", "Balboa hyliano"}, - Text{"Rupee (50)", "Rubis (50)", "Peso hyliano"}}; - trickNameTable[RG_HUGE_RUPEE] = { - Text{"Hugo", "Or Rubi", "Oro Rubi"}, - Text{"Two Hundred Rubies", "deux cents rubis", "Doscientos rubíes"}, - Text{"Diamond", "Diamant", "Diamante"}, - Text{"Huge Ruby", "Énorme rubis", "Rubi gigante"}, - Text{"Two Hundred Rupees", "Deux cent rubis", "Euro hyliano"}, - Text{"Rupee (200)", "Rubis (200)", "Dólar hyliano"}}; - trickNameTable[RG_PIECE_OF_HEART] = { - Text{"Pizza Heart", "Fromage de cœur", "Pieza de Chorizo"}, - Text{"Little Bit Of Love", "Un peu d'amour", "Un poco de amor"}, - Text{"Rare Peach Stone", "Pierre de pêche rare", "Pierre de pêche rare"}}; - trickNameTable[RG_HEART_CONTAINER] = { - Text{"Crystal Heart", "Cœur de cristal", "Corazón de cristal"}, - Text{"Life Heart", "Cœur de vie", "Vida Corazón"}, - Text{"Lots of Love", "Beaucoup d'amour", "Mucho amor"}}; - trickNameTable[RG_TRIFORCE_PIECE] = { - Text{"Piece of Cheese", "Morceau de Fromage", "Piece of Cheese"}, - Text{"Triforce Shard", "Éclat de Triforce", "Triforce Shard"}, - Text{"Shiny Rock", "Caiiloux Brillant", "Shiny Rock"}}; - trickNameTable[RG_GOHMA_SOUL] = { - Text{"Spider Sense", "", ""}, - Text{"Deku Spirit", "", ""}, - Text("Ghost of Ghoma", "", "")}; - trickNameTable[RG_KING_DODONGO_SOUL] = { - Text{"Lizard Soul", "", ""}, - Text{"Regal Remains", "", ""}, - Text{"Dodongo's Core", "", ""}}; - trickNameTable[RG_BARINADE_SOUL] = { - Text{"Parasitic Poltergeist", "", ""}, - Text{"Jabu Insides", "", ""}, - Text{"Barinade Bacteria", "", ""}}; - trickNameTable[RG_PHANTOM_GANON_SOUL] = { - Text{"Bigger Poe", "", ""}, - Text{"Sacred Forest Pine Tree", "", ""}, - Text{"Ganon's Phantom", "", ""}}; - trickNameTable[RG_VOLVAGIA_SOUL] = { - Text{"Dragon Roast", "", ""}, - Text{"Hot n' Ready", "", ""}, - Text{"Volvagia's Vitality", "", ""}}; - trickNameTable[RG_MORPHA_SOUL] = { - Text{"Dihydrogen Monoxide", "", ""}, - Text{"Morpha Molecules", "", ""}, - Text{"Wet Stuff", "", ""}}; - trickNameTable[RG_BONGO_BONGO_SOUL] = { - Text{"Shadow Soul", "", ""}, - Text{"Dark Essence", "", ""}, - Text{"Bongo Bongo's Bongo", "", ""}}; - trickNameTable[RG_TWINROVA_SOUL] = { - Text{"Sandy Ashes", "", ""}, - Text{"Spiritual Spirit", "", ""}, - Text{"Twin Rovers", "", ""}}; - trickNameTable[RG_GANON_SOUL] = { - Text{"Pure Evil", "", ""}, - Text{"Ganon's Ghost", "", ""}, - Text{"Pork", "", ""}}; - trickNameTable[RG_FISHING_POLE] = { - Text{"Fish Tickler", "Fish Tickler", "Fish Tickler"}, - Text{"Floating Lure", "Floating Lure", "Floating Lure"}, - Text{"Fishing Reel", "Fishing Reel", "Fishing Reel"}}; + trickNameTable[RG_RECOVERY_HEART] = { + Text{"Love", "Bisou", "Te amo"}, + Text{"Life", "Vie", "vida"}, + Text{"HP", "VP", "VP"} + }; + trickNameTable[RG_GREEN_RUPEE] = { + Text{"False Greg", "Faux Greg", "Falso Greg"}, + Text{"One Ruby", "Un rubis", "Un rubí"}, + Text{"Rupoor (1)", "Roupir (1)", "Rupobre (1)"}, + Text{"One Rupee", "Un rubis", "Guaraní hyliano"}, + Text{"Rupee (1)", "Rubis (1)", "Peso hyliano"} + }; + trickNameTable[RG_BLUE_RUPEE] = { + Text{"Blupee", "Bleubi", "Azupia"}, + Text{"Five Rubies", "Cinq Rubys", "Cinco rubíes"}, + Text{"Five Rupees", "Cinq rubis", "Bolívar hyliano"}, + Text{"Rupee (5)", "Rubis (5)", "Peso hyliano"}, + Text{"Rupoor (5)", "Roupir (5)", "Rupobre (5)"} + }; + trickNameTable[RG_RED_RUPEE] = { + Text{"Big 20", "Grand 20", "Los 20 grandes"}, + Text{"Twenty Rubies", "vingt rubis", "Veinte rubíes"}, + Text{"Rupoor (20)", "Roupir (20)", "Rupobre (20)"}, + Text{"Twenty Rupees", "Vingt rubis", "Colon hyliano"}, + Text{"Rupee (20)", "Rubis (20)", "Peso hyliano"} + }; + trickNameTable[RG_PURPLE_RUPEE] = { + Text{"Purpee", "pourbi", "morupiua"}, + Text{"Fifty Rubies", "cinquante rubis", "Cincuenta rubíes"}, + Text{"Rupoor (50)", "Roupir (50)", "Rupobre (50)"}, + Text{"Fifty Rupees", "Cinquante rubis", "Balboa hyliano"}, + Text{"Rupee (50)", "Rubis (50)", "Peso hyliano"} + }; + trickNameTable[RG_HUGE_RUPEE] = { + Text{"Hugo", "Or Rubi", "Oro Rubi"}, + Text{"Two Hundred Rubies", "deux cents rubis", "Doscientos rubíes"}, + Text{"Diamond", "Diamant", "Diamante"}, + Text{"Huge Ruby", "Énorme rubis", "Rubi gigante"}, + Text{"Two Hundred Rupees", "Deux cent rubis", "Euro hyliano"}, + Text{"Rupee (200)", "Rubis (200)", "Dólar hyliano"} + }; + trickNameTable[RG_PIECE_OF_HEART] = { + Text{"Pizza Heart", "Fromage de cœur", "Pieza de Chorizo"}, + Text{"Little Bit Of Love", "Un peu d'amour", "Un poco de amor"}, + Text{"Rare Peach Stone", "Pierre de pêche rare", "Pierre de pêche rare"} + }; + trickNameTable[RG_HEART_CONTAINER] = { + Text{"Crystal Heart", "Cœur de cristal", "Corazón de cristal"}, + Text{"Life Heart", "Cœur de vie", "Vida Corazón"}, + Text{"Lots of Love", "Beaucoup d'amour", "Mucho amor"} + }; + trickNameTable[RG_TRIFORCE_PIECE] = { + Text{"Piece of Cheese", "Morceau de Fromage", "Piece of Cheese"}, + Text{"Triforce Shard", "Éclat de Triforce", "Triforce Shard"}, + Text{"Shiny Rock", "Caiiloux Brillant", "Shiny Rock"} + }; - trickNameTable[RG_OCARINA_A_BUTTON] = { - Text{"Ocarina J Button", "", ""}, - Text{"Ocarina Ayy Button", "", ""}, - Text{"Ocarina A Trigger", "", ""} }; - trickNameTable[RG_OCARINA_C_UP_BUTTON] = { - Text{"Ocarina C North Button", "", ""}, - Text{"Ocarina C App Button", "", ""}, - Text{"Ocarina Sup Button", "", ""} }; - trickNameTable[RG_OCARINA_C_DOWN_BUTTON] = { - Text{"Ocarina C South Button", "", ""}, - Text{"Ocarina Z Down Button", "", ""}, - Text{"Ocarina See Down Button", "", ""}, - Text{"Ocarina C Dawn Button", "", ""} }; - trickNameTable[RG_OCARINA_C_LEFT_BUTTON] = { - Text{"Ocarina C West Button", "", ""}, - Text{"Ocarina Sea Left Button", "", ""}, - Text{"Ocarina C Lift Button", "", ""}, - Text{"Ocarina Rewind Button", "", ""} }; - trickNameTable[RG_OCARINA_C_RIGHT_BUTTON] = { - Text{"Ocarina C East Button", "", ""}, - Text{"Ocarina C Wright Button", "", ""}, - Text{"Overworld C Right Button", "", ""} }; + trickNameTable[RG_GOHMA_SOUL] = { + Text{"Spider Sense", "", ""}, + Text{"Deku Spirit", "", ""}, + Text{"Ghost of Ghoma", "", ""} + }; + trickNameTable[RG_KING_DODONGO_SOUL] = { + Text{"Lizard Soul", "", ""}, + Text{"Regal Remains", "", ""}, + Text{"Dodongo's Core", "", ""} + }; + trickNameTable[RG_BARINADE_SOUL] = { + Text{"Parasitic Poltergeist", "", ""}, + Text{"Jabu Insides", "", ""}, + Text{"Barinade Bacteria", "", ""} + }; + trickNameTable[RG_PHANTOM_GANON_SOUL] = { + Text{"Bigger Poe", "", ""}, + Text{"Sacred Forest Pine Tree", "", ""}, + Text{"Ganon's Phantom", "", ""} + }; + trickNameTable[RG_VOLVAGIA_SOUL] = { + Text{"Dragon Roast", "", ""}, + Text{"Hot n' Ready", "", ""}, + Text{"Volvagia's Vitality", "", ""} + }; + trickNameTable[RG_MORPHA_SOUL] = { + Text{"Dihydrogen Monoxide", "", ""}, + Text{"Morpha Molecules", "", ""}, + Text{"Wet Stuff", "", ""} + }; + trickNameTable[RG_BONGO_BONGO_SOUL] = { + Text{"Shadow Soul", "", ""}, + Text{"Dark Essence", "", ""}, + Text{"Bongo Bongo's Bongo", "", ""} + }; + trickNameTable[RG_TWINROVA_SOUL] = { + Text{"Sandy Ashes", "", ""}, + Text{"Spiritual Spirit", "", ""}, + Text{"Twin Rovers", "", ""} + }; + trickNameTable[RG_GANON_SOUL] = { + Text{"Pure Evil", "", ""}, + Text{"Ganon's Ghost", "", ""}, + Text{"Pork", "", ""} + }; -/* - //Names for individual upgrades, in case progressive names are replaced - trickNameTable[GI_HOOKSHOT] = { - Text{"Grappling Hook", "Grappin-griffe", "Gancho lanzable"}, - Text{"Clawshot", "Lance-chaîne", "Zarpa"}, - Text{"Gripshot", "Grappince", "Enganchador"}}; - trickNameTable[GI_LONGSHOT] = { - Text{"Longshot, no strings attached", "Grappin sans attrape", "Gancho lanzable más largo"}, - Text{"Double Clawshot", "Double-grappin", "Superzarpa"}, - Text{"Switch Hook", "Great grappin", "Gancho chulo"}}; - trickNameTable[GI_BOMB_BAG_1] = { - Text{"Bomb Capacity (20)", "Capacité de bombes (20)", "Bolsa de bombas (contiene 20)"}, - Text{"Bronze Bomb Bag", "Sac de Bombes de bronze", "Saco de bronce de bombas"}, - Text{"Small Bomb Bag", "Petit Sac de Bombes", "Zurrón de bombas pequeño"}}; - trickNameTable[GI_BOMB_BAG_2] = { - Text{"Bomb Capacity (30)", "Capacité de bombes (30)", "Bolsa de bombas (contiene 30)"}, - Text{"Silver Bomb Bag", "Sac de Bombes d'argent", "Saco plateado de bombas"}, - Text{"Medium Bomb Bag", "Sac de Bombes moyen", "Zurrón de bombas mediano"}}; - trickNameTable[GI_BOMB_BAG_3] = { - Text{"Bomb Capacity (40)", "Capacité de bombes (40)", "Bolsa de bombas (contiene 40)"}, - Text{"Golden Bomb Bag", "Sac de Bombes d'or", "Saco dorado de bombas"}, - Text{"Large Bomb Bag", "Gros Sac de Bombes", "Zurrón de bombas grande"}}; - trickNameTable[GI_BOW_1] = { - Text{"Bow", "Arc", "Arco del Hada"}, - Text{"Hero's Bow", "Arc du héros", "Arco del héroe"}, - Text{"Small Quiver", "Petit carquois", "Saco de flechas pequeño"}}; - trickNameTable[GI_BOW_2] = { - Text{"Arrow Capacity (40)", "Capacité de flèches (40)", "Capacidad de flechas (40)"}, - Text{"Silver Quiver", "Carquois d'argent", "Carcaj plateado"}, - Text{"Medium Quiver", "Carquois moyen", "Saco de flechas mediano"}}; - trickNameTable[GI_BOW_3] = { - Text{"Arrow Capacity (50)", "Capacité de flèches (50)", "Capacidad de flechas (50)"}, - Text{"Golden Quiver", "Carquois d'or", "Carcaj dorado"}, - Text{"Large Quiver", "Gros carquois", "Saco de flechas grande"}}; - trickNameTable[GI_SLINGSHOT_1] = { - Text{"Slingshot", "Lance-Pierre", "Tirachinas del Hada"}, - Text{"Scattershot", "Lance-Pierre rafale", "Tirachinas múltiple"}, - Text{"Small Seed Satchel", "Petit sac de graines", "Bolsa de semillas pequeña"}}; - trickNameTable[GI_SLINGSHOT_2] = { - Text{"Deku Seed Capacity (40)", "Capacité de graines (40)", "Capacidad de semillas (40)"}, - Text{"Silver Deku Seed Bullet Bag", "Sac de graines d'argent", "Bolsa de balas (contiene 40)"}, - Text{"Medium Seed Satchel", "Sac de graines moyen", "Bolsa de semillas mediana"}}; - trickNameTable[GI_SLINGSHOT_3] = { - Text{"Deku Seed Capacity (50)", "Capacité de graines (50)", "Capacidad de semillas (50)"}, - Text{"Golden Deku Seed Bullet Bag", "Sac de graines d'or", "Bolsa de balas (contiene 50)"}, - Text{"Large Seed Satchel", "Gros sac de graines", "Bolsa de semillas grande"}}; - trickNameTable[GI_STRENGTH_1] = { - Text{"Goron's Gauntlet", "Gantelet Goron", "Brazalete amarillo"}, - Text{"Power Bracelet", "Bracelet de force", "Brazalete de fuerza"}, - Text{"Magic Bracelet", "Bracelet de Lavio", "Brazalete de Ravio"}}; - trickNameTable[GI_STRENGTH_2] = { - Text{"Silver Bracelets", "Bracelets d'argent", "Guantes Moguma"}, - Text{"Power Gloves", "Gant de puissance", "Guante del Poder"}, - Text{"Magic Gauntlets", "Gantelet magique", "Guante mágico"}}; - trickNameTable[GI_STRENGTH_3] = { - Text{"Golden Bracelets", "Bracelets d'or", "Guantelete de Thanos"}, - Text{"Titan's Mitts", "Moufle de titan", "Guantes de Titán"}, - Text{"Magnetic Gloves", "Magnéto-gants", "Guantes de fuego"}}; - trickNameTable[GI_SCALE_1] = { - Text{"Silver Pearl", "Perle d'argent", "Perla de Plata progresiva"}, - Text{"Adult Scale", "Écaille d'adulte", "Bola de bolos zora"}, - Text{"Zora Scale", "Écaille Zora", "Escama de Zora"}}; - trickNameTable[GI_SCALE_2] = { - Text{"Golden Pearl", "Perle d'or", "Perla de Oro progresiva"}, - Text{"Giant Scale", "Écaille de géant", "Escama de Faren"}, - Text{"Water Dragon Scale", "Écaille du dragon de l'eau", "Escama de dragón acuático"}}; - trickNameTable[GI_WALLET_1] = { - Text{"Rupee Capacity (200)", "Capacité de rubis (200)", "Capacidad de rupias (200)"}, - Text{"Silver Wallet", "Bourse d'argent", "Cartera de rupias de adulto"}, - Text{"Medium Wallet", "Bourse moyenne", "Zurrón de rupias mediano"}}; - trickNameTable[GI_WALLET_2] = { - Text{"Rupee Capacity (500)", "Capacité de rubis (500)", "Capacidad de rupias (500)"}, - Text{"Golden Wallet", "Bourse d'or", "Cartera de rupias gigante"}, - Text{"Large Wallet", "Grosse Bourse", "Zurrón de rupias grande"}}; - trickNameTable[GI_WALLET_3] = { - Text{"Rupee Capacity (999)", "Capacité de rubis (999)", "Capacidad de rupias (999)"}, - Text{"Golden Wallet", "Bourse d'or", "Cartera de ricachón"}, - Text{"Large Wallet", "Grosse Bourse", "Zurrón de rupias gigante"}}; - trickNameTable[GI_DEKU_NUT_UPGRADE_1] = { - Text{"Deku Bomb Capacity (30)", "Capacité de bombes Mojo (30)", "Capacidad de semillas deku (40)"}, - Text{"Baba Nut Capacity (30)", "Capacité de noix Baba (30)", "Capacidad de nueces baba (40)"}, - Text{"Deku Nut Pack (30)", "Paquet de noix Mojo (30)", "Capacidad de nueces mojo (40)"}}; - trickNameTable[GI_DEKU_NUT_UPGRADE_2] = { - Text{"Deku Bomb Capacity (40)", "Capacité de bombes Mojo (40)", "Capacidad de semillas deku (50)"}, - Text{"Baba Nut Capacity (40)", "Capacité de noix Baba (40)", "Capacidad de nueces baba (50)"}, - Text{"Deku Nut Pack (40)", "Paquet de noix Mojo (40)", "Capacidad de nueces mojo (50)"}}; - trickNameTable[GI_DEKU_STICK_UPGRADE_1] = { - Text{"Deku Rod Capacity (20)", "Capacité de tiges Mojo (20)", "Capacidad de palos mojo (20)"}, - Text{"Boko Stick Capacity (20)", "Capacité de Bâtons Boko (20)", "Capacidad de palos boko (20)"}, - Text{"Deku Stick Pack (20)", "Paquet de bâtons Mojo (20)", "Capacidad de bastones deku (20)"}}; - trickNameTable[GI_DEKU_STICK_UPGRADE_2] = { - Text{"Deku Rod Capacity (30)", "Capacité de tiges Mojo (30)", "Capacidad de palos mojo (30)"}, - Text{"Boko Stick Capacity (30)", "Capacité de Bâtons Boko (30)", "Capacidad de palos boko (30)"}, - Text{"Deku Stick Pack (30)", "Paquet de bâtons Mojo (30)", "Capacidad de bastones deku (30)"}}; - trickNameTable[GI_MAGIC_1] = { - Text{"Stamina Meter", "Jauge d'endurance", "Medidor de vigor"}, - Text{"Energy Meter", "Jauge d'énergie", "Medidor de energía"}, - Text{"Magic Powder", "Poudre magique", "Medidor de carga"}}; - trickNameTable[GI_MAGIC_2] = { - Text{"Enhanced Stamina Meter", "Jauge d'endurance améliorée", "Medidor de vigor mejorado"}, - Text{"Enhanced Energy Meter", "Jauge d'énergie améliorée", "Medidor de energía mejorado"}, - Text{"Enhanced Magic Powder", "Poudre magique améliorée", "Medidor de carga mejorado"}}; - trickNameTable[GI_OCARINA_1] = { - Text{"Ocarina", "Ocarina", "Ocarina"}, - Text{"Saria's Ocarina", "Ocarina de Saria", "Ocarina de Saria"}, - Text{"Wood Ocarina", "Ocarina de bois", "Ocarina del Hada"}}; - trickNameTable[GI_OCARINA_2] = { - Text{"Flute", "Flûte", "Flauta"}, - Text{"Zelda's Ocarina", "Ocarina de Zelda", "Ocarina de Zelda"}, - Text{"Ocarina of Winds", "Ocarina des vents", "Ocarina del Viento"}}; - trickNameTable[GI_CUCCO] = { - Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada"}, - Text{"Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko"}, - Text{"Hatched Cucco", "Cocotte éclose", "Pollo"}}; - trickNameTable[GI_MASK_KEATON] = { - Text{"Kee... Something Mask", "Masque de Quiche", "Máscara Kealgo"}, - Text{"Kitsune Mask", "Masque de Kitsune", "Máscara Kitsune"}, - Text{"Kafei's Mask", "Masque de Kafei", "Máscara de Kafei"}}; - trickNameTable[GI_MASK_SKULL] = { - Text{"Skull Kid's Mask", "Masque de Skull Kid", "Máscara de Skull Kid"}, - Text{"Stalfos Mask", "Masque de squelette", "Máscara de Stalfos"}, - Text{"Captain's Hat", "Heaume du capitaine", "Casco del capitán"}}; - trickNameTable[GI_MASK_SPOOKY] = { - Text{"Skrik Mask", "Masque Skrik", "Máscara Escalofriante"}, - Text{"ReDead Mask", "Masque de Remort", "Máscara de ReDead"}, - Text{"Gibdo Mask", "Masque de Gibdo", "Careta de Gibdo"}}; - trickNameTable[GI_MASK_BUNNY] = { - Text{"Peppy Mask", "Masque de Peppy", "Capucha de Pascua"}, - Text{"Bunny Ears", "Oreilles de lapin", "Orejas de conejo"}, - Text{"Postman's Hat", "Casquette du facteur", "Gorra de cartero"}}; - trickNameTable[GI_MASK_GORON] = { - Text{"Goro Mask", "Masque Goro", "Máscara Goro"}, - Text{"Mask of Goron", "Masque des Gorons", "Máscara de los Goron"}, - Text{"Darunia Mask", "Masque de Darunia", "Máscara de Darmani"}}; - trickNameTable[GI_MASK_ZORA] = { - Text{"Zola Mask", "Masque Zola", "Máscara Zola"}, - Text{"Mask of Zora", "Masque des Zoras", "Máscara de los Zora"}, - Text{"Ruto Mask", "Masque de Ruto", "Máscara de Mikau"}}; - trickNameTable[GI_MASK_GERUDO] = { - Text{"Ganguro Mask", "Masque de Ganguro", "Máscara Canguro"}, - Text{"Mask of Gerudo", "Masque des Gerudos", "Máscara de las Gerudo"}, - Text{"Nabooru Mask", "Masque de Nabooru", "Máscara de Nabooru"}}; - trickNameTable[GI_MASK_TRUTH] = { - Text{"Sheikah Mask", "Masque Sheikah", "Máscara Sheikah"}, - Text{"Mask of Gossip", "Masque de potins", "Máscara chismosa"}, - Text{"Eye of Truth", "oeil de vérité", "Ojo de la Verdad"}};*/ -} + trickNameTable[RG_FISHING_POLE] = { + Text{"Fish Tickler", "Fish Tickler", "Fish Tickler"}, + Text{"Floating Lure", "Floating Lure", "Floating Lure"}, + Text{"Fishing Reel", "Fishing Reel", "Fishing Reel"} + }; -//Generate a fake name for the ice trap based on the item it's displayed as -Text GetIceTrapName(uint8_t id) { - //If the trick names table has not been initialized, do so - if (!initTrickNames) { - InitTrickNames(); - initTrickNames = true; - } - //Randomly get the easy, medium, or hard name for the given item id - return RandomElement(trickNameTable[id]); -} + trickNameTable[RG_OCARINA_A_BUTTON] = { + Text{"Ocarina J Button", "", ""}, + Text{"Ocarina Ayy Button", "", ""}, + Text{"Ocarina A Trigger", "", ""} + }; + trickNameTable[RG_OCARINA_C_UP_BUTTON] = { + Text{"Ocarina C North Button", "", ""}, + Text{"Ocarina C App Button", "", ""}, + Text{"Ocarina Sup Button", "", ""} + }; + trickNameTable[RG_OCARINA_C_DOWN_BUTTON] = { + Text{"Ocarina C South Button", "", ""}, + Text{"Ocarina Z Down Button", "", ""}, + Text{"Ocarina See Down Button", "", ""}, + Text{"Ocarina C Dawn Button", "", ""} + }; + trickNameTable[RG_OCARINA_C_LEFT_BUTTON] = { + Text{"Ocarina C West Button", "", ""}, + Text{"Ocarina Sea Left Button", "", ""}, + Text{"Ocarina C Lift Button", "", ""}, + Text{"Ocarina Rewind Button", "", ""} + }; + trickNameTable[RG_OCARINA_C_RIGHT_BUTTON] = { + Text{"Ocarina C East Button", "", ""}, + Text{"Ocarina C Wright Button", "", ""}, + Text{"Overworld C Right Button", "", ""} + }; -//Get shop index based on a given location -static std::map ShopNameToNum = {{"KF Shop", 0}, {"Kak Potion Shop", 1}, {"MK Bombchu Shop", 2}, {"MK Potion Shop", 3}, - {"MK Bazaar", 4}, {"Kak Bazaar", 5}, {"ZD Shop", 6}, {"GC Shop", 7}}; -int GetShopIndex(RandomizerCheck loc) { - //Kind of hacky, but extract the shop and item position from the name - const std::string& name(Rando::StaticData::GetLocation(loc)->GetName()); - int split = name.find(" Item "); - std::string_view shop(name.c_str(), split); - int pos = std::stoi(name.substr(split+6, 1)) - 1; - int shopnum = ShopNameToNum[shop]; - return shopnum*8 + pos; + /* + //Names for individual upgrades, in case progressive names are replaced + trickNameTable[GI_HOOKSHOT] = { + Text{"Grappling Hook", "Grappin-griffe", "Gancho lanzable"}, + Text{"Clawshot", "Lance-chaîne", "Zarpa"}, + Text{"Gripshot", "Grappince", "Enganchador"} + }; + trickNameTable[GI_LONGSHOT] = { + Text{"Longshot, no strings attached", "Grappin sans attrape", "Gancho lanzable más largo"}, + Text{"Double Clawshot", "Double-grappin", "Superzarpa"}, + Text{"Switch Hook", "Great grappin", "Gancho chulo"} + }; + trickNameTable[GI_BOMB_BAG_1] = { + Text{"Bomb Capacity (20)", "Capacité de bombes (20)", "Bolsa de bombas (contiene 20)"}, + Text{"Bronze Bomb Bag", "Sac de Bombes de bronze", "Saco de bronce de bombas"}, + Text{"Small Bomb Bag", "Petit Sac de Bombes", "Zurrón de bombas pequeño"} + }; + trickNameTable[GI_BOMB_BAG_2] = { + Text{"Bomb Capacity (30)", "Capacité de bombes (30)", "Bolsa de bombas (contiene 30)"}, + Text{"Silver Bomb Bag", "Sac de Bombes d'argent", "Saco plateado de bombas"}, + Text{"Medium Bomb Bag", "Sac de Bombes moyen", "Zurrón de bombas mediano"} + }; + trickNameTable[GI_BOMB_BAG_3] = { + Text{"Bomb Capacity (40)", "Capacité de bombes (40)", "Bolsa de bombas (contiene 40)"}, + Text{"Golden Bomb Bag", "Sac de Bombes d'or", "Saco dorado de bombas"}, + Text{"Large Bomb Bag", "Gros Sac de Bombes", "Zurrón de bombas grande"} + }; + trickNameTable[GI_BOW_1] = { + Text{"Bow", "Arc", "Arco del Hada"}, + Text{"Hero's Bow", "Arc du héros", "Arco del héroe"}, + Text{"Small Quiver", "Petit carquois", "Saco de flechas pequeño"} + }; + trickNameTable[GI_BOW_2] = { + Text{"Arrow Capacity (40)", "Capacité de flèches (40)", "Capacidad de flechas (40)"}, + Text{"Silver Quiver", "Carquois d'argent", "Carcaj plateado"}, + Text{"Medium Quiver", "Carquois moyen", "Saco de flechas mediano"} + }; + trickNameTable[GI_BOW_3] = { + Text{"Arrow Capacity (50)", "Capacité de flèches (50)", "Capacidad de flechas (50)"}, + Text{"Golden Quiver", "Carquois d'or", "Carcaj dorado"}, + Text{"Large Quiver", "Gros carquois", "Saco de flechas grande"} + }; + trickNameTable[GI_SLINGSHOT_1] = { + Text{"Slingshot", "Lance-Pierre", "Tirachinas del Hada"}, + Text{"Scattershot", "Lance-Pierre rafale", "Tirachinas múltiple"}, + Text{"Small Seed Satchel", "Petit sac de graines", "Bolsa de semillas pequeña"} + }; + trickNameTable[GI_SLINGSHOT_2] = { + Text{"Deku Seed Capacity (40)", "Capacité de graines (40)", "Capacidad de semillas (40)"}, + Text{"Silver Deku Seed Bullet Bag", "Sac de graines d'argent", "Bolsa de balas (contiene 40)"}, + Text{"Medium Seed Satchel", "Sac de graines moyen", "Bolsa de semillas mediana"} + }; + trickNameTable[GI_SLINGSHOT_3] = { + Text{"Deku Seed Capacity (50)", "Capacité de graines (50)", "Capacidad de semillas (50)"}, + Text{"Golden Deku Seed Bullet Bag", "Sac de graines d'or", "Bolsa de balas (contiene 50)"}, + Text{"Large Seed Satchel", "Gros sac de graines", "Bolsa de semillas grande"} + }; + trickNameTable[GI_STRENGTH_1] = { + Text{"Goron's Gauntlet", "Gantelet Goron", "Brazalete amarillo"}, + Text{"Power Bracelet", "Bracelet de force", "Brazalete de fuerza"}, + Text{"Magic Bracelet", "Bracelet de Lavio", "Brazalete de Ravio"} + }; + trickNameTable[GI_STRENGTH_2] = { + Text{"Silver Bracelets", "Bracelets d'argent", "Guantes Moguma"}, + Text{"Power Gloves", "Gant de puissance", "Guante del Poder"}, + Text{"Magic Gauntlets", "Gantelet magique", "Guante mágico"} + }; + trickNameTable[GI_STRENGTH_3] = { + Text{"Golden Bracelets", "Bracelets d'or", "Guantelete de Thanos"}, + Text{"Titan's Mitts", "Moufle de titan", "Guantes de Titán"}, + Text{"Magnetic Gloves", "Magnéto-gants", "Guantes de fuego"} + }; + trickNameTable[GI_SCALE_1] = { + Text{"Silver Pearl", "Perle d'argent", "Perla de Plata progresiva"}, + Text{"Adult Scale", "Écaille d'adulte", "Bola de bolos zora"}, + Text{"Zora Scale", "Écaille Zora", "Escama de Zora"} + }; + trickNameTable[GI_SCALE_2] = { + Text{"Golden Pearl", "Perle d'or", "Perla de Oro progresiva"}, + Text{"Giant Scale", "Écaille de géant", "Escama de Faren"}, + Text{"Water Dragon Scale", "Écaille du dragon de l'eau", "Escama de dragón acuático"} + }; + trickNameTable[GI_WALLET_1] = { + Text{"Rupee Capacity (200)", "Capacité de rubis (200)", "Capacidad de rupias (200)"}, + Text{"Silver Wallet", "Bourse d'argent", "Cartera de rupias de adulto"}, + Text{"Medium Wallet", "Bourse moyenne", "Zurrón de rupias mediano"} + }; + trickNameTable[GI_WALLET_2] = { + Text{"Rupee Capacity (500)", "Capacité de rubis (500)", "Capacidad de rupias (500)"}, + Text{"Golden Wallet", "Bourse d'or", "Cartera de rupias gigante"}, + Text{"Large Wallet", "Grosse Bourse", "Zurrón de rupias grande"} + }; + trickNameTable[GI_WALLET_3] = { + Text{"Rupee Capacity (999)", "Capacité de rubis (999)", "Capacidad de rupias (999)"}, + Text{"Golden Wallet", "Bourse d'or", "Cartera de ricachón"}, + Text{"Large Wallet", "Grosse Bourse", "Zurrón de rupias gigante"} + }; + trickNameTable[GI_DEKU_NUT_UPGRADE_1] = { + Text{"Deku Bomb Capacity (30)", "Capacité de bombes Mojo (30)", "Capacidad de semillas deku (40)"}, + Text{"Baba Nut Capacity (30)", "Capacité de noix Baba (30)", "Capacidad de nueces baba (40)"}, + Text{"Deku Nut Pack (30)", "Paquet de noix Mojo (30)", "Capacidad de nueces mojo (40)"} + }; + trickNameTable[GI_DEKU_NUT_UPGRADE_2] = { + Text{"Deku Bomb Capacity (40)", "Capacité de bombes Mojo (40)", "Capacidad de semillas deku (50)"}, + Text{"Baba Nut Capacity (40)", "Capacité de noix Baba (40)", "Capacidad de nueces baba (50)"}, + Text{"Deku Nut Pack (40)", "Paquet de noix Mojo (40)", "Capacidad de nueces mojo (50)"} + }; + trickNameTable[GI_DEKU_STICK_UPGRADE_1] = { + Text{"Deku Rod Capacity (20)", "Capacité de tiges Mojo (20)", "Capacidad de palos mojo (20)"}, + Text{"Boko Stick Capacity (20)", "Capacité de Bâtons Boko (20)", "Capacidad de palos boko (20)"}, + Text{"Deku Stick Pack (20)", "Paquet de bâtons Mojo (20)", "Capacidad de bastones deku (20)"} + }; + trickNameTable[GI_DEKU_STICK_UPGRADE_2] = { + Text{"Deku Rod Capacity (30)", "Capacité de tiges Mojo (30)", "Capacidad de palos mojo (30)"}, + Text{"Boko Stick Capacity (30)", "Capacité de Bâtons Boko (30)", "Capacidad de palos boko (30)"}, + Text{"Deku Stick Pack (30)", "Paquet de bâtons Mojo (30)", "Capacidad de bastones deku (30)"} + }; + trickNameTable[GI_MAGIC_1] = { + Text{"Stamina Meter", "Jauge d'endurance", "Medidor de vigor"}, + Text{"Energy Meter", "Jauge d'énergie", "Medidor de energía"}, + Text{"Magic Powder", "Poudre magique", "Medidor de carga"} + }; + trickNameTable[GI_MAGIC_2] = { + Text{"Enhanced Stamina Meter", "Jauge d'endurance améliorée", "Medidor de vigor mejorado"}, + Text{"Enhanced Energy Meter", "Jauge d'énergie améliorée", "Medidor de energía mejorado"}, + Text{"Enhanced Magic Powder", "Poudre magique améliorée", "Medidor de carga mejorado"} + }; + trickNameTable[GI_OCARINA_1] = { + Text{"Ocarina", "Ocarina", "Ocarina"}, + Text{"Saria's Ocarina", "Ocarina de Saria", "Ocarina de Saria"}, + Text{"Wood Ocarina", "Ocarina de bois", "Ocarina del Hada"} + }; + trickNameTable[GI_OCARINA_2] = { + Text{"Flute", "Flûte", "Flauta"}, + Text{"Zelda's Ocarina", "Ocarina de Zelda", "Ocarina de Zelda"}, + Text{"Ocarina of Winds", "Ocarina des vents", "Ocarina del Viento"} + }; + trickNameTable[GI_CUCCO] = { + Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada"}, + Text{"Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko"}, + Text{"Hatched Cucco", "Cocotte éclose", "Pollo"} + }; + trickNameTable[GI_MASK_KEATON] = { + Text{"Kee... Something Mask", "Masque de Quiche", "Máscara Kealgo"}, + Text{"Kitsune Mask", "Masque de Kitsune", "Máscara Kitsune"}, + Text{"Kafei's Mask", "Masque de Kafei", "Máscara de Kafei"} + }; + trickNameTable[GI_MASK_SKULL] = { + Text{"Skull Kid's Mask", "Masque de Skull Kid", "Máscara de Skull Kid"}, + Text{"Stalfos Mask", "Masque de squelette", "Máscara de Stalfos"}, + Text{"Captain's Hat", "Heaume du capitaine", "Casco del capitán"} + }; + trickNameTable[GI_MASK_SPOOKY] = { + Text{"Skrik Mask", "Masque Skrik", "Máscara Escalofriante"}, + Text{"ReDead Mask", "Masque de Remort", "Máscara de ReDead"}, + Text{"Gibdo Mask", "Masque de Gibdo", "Careta de Gibdo"} + }; + trickNameTable[GI_MASK_BUNNY] = { + Text{"Peppy Mask", "Masque de Peppy", "Capucha de Pascua"}, + Text{"Bunny Ears", "Oreilles de lapin", "Orejas de conejo"}, + Text{"Postman's Hat", "Casquette du facteur", "Gorra de cartero"} + }; + trickNameTable[GI_MASK_GORON] = { + Text{"Goro Mask", "Masque Goro", "Máscara Goro"}, + Text{"Mask of Goron", "Masque des Gorons", "Máscara de los Goron"}, + Text{"Darunia Mask", "Masque de Darunia", "Máscara de Darmani"} + }; + trickNameTable[GI_MASK_ZORA] = { + Text{"Zola Mask", "Masque Zola", "Máscara Zola"}, + Text{"Mask of Zora", "Masque des Zoras", "Máscara de los Zora"}, + Text{"Ruto Mask", "Masque de Ruto", "Máscara de Mikau"} + }; + trickNameTable[GI_MASK_GERUDO] = { + Text{"Ganguro Mask", "Masque de Ganguro", "Máscara Canguro"}, + Text{"Mask of Gerudo", "Masque des Gerudos", "Máscara de las Gerudo"}, + Text{"Nabooru Mask", "Masque de Nabooru", "Máscara de Nabooru"} + }; + trickNameTable[GI_MASK_TRUTH] = { + Text{"Sheikah Mask", "Masque Sheikah", "Máscara Sheikah"}, + Text{"Mask of Gossip", "Masque de potins", "Máscara chismosa"}, + Text{"Eye of Truth", "oeil de vérité", "Ojo de la Verdad"} + }; + */ } -//Without this transformed index, shop-related tables and arrays would need 64 entries- But only half of that is needed for shopsanity -//So we use this transformation to map only important indices to an array with 32 entries in the following manner: -//Shop index: 4 5 6 7 12 13 14 15 20 21 22 23... -//Transformed: 0 1 2 3 4 5 6 7 8 9 10 11... -//So we first divide the shop index by 4, then by 2 which basically tells us the index of the shop it's in, -//then multiply by 4 since there are 4 items per shop -//And finally we use a modulo by 4 to get the index within the "shop" of 4 items, and add -int TransformShopIndex(int index) { - return 4*((index / 4) / 2) + index % 4; -} +//Generate a fake name for the ice trap based on the item it's displayed as +Text GetIceTrapName(uint8_t id) { + //If the trick names table has not been initialized, do so + if (!initTrickNames) { + InitTrickNames(); + initTrickNames = true; + } + //Randomly get the easy, medium, or hard name for the given item id + return RandomElement(trickNameTable[id]); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.hpp b/soh/soh/Enhancements/randomizer/3drando/shops.hpp index 33cf57ff4be..152e64d0f1d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.hpp @@ -2,7 +2,6 @@ #include "../context.h" #include -#include struct ItemAndPrice { Text Name; @@ -16,7 +15,5 @@ extern int GetRandomShopPrice(); extern int16_t GetRandomScrubPrice(); extern int GetShopsanityReplaceAmount(); extern Text GetIceTrapName(uint8_t id); -extern int GetShopIndex(RandomizerCheck loc); -extern int TransformShopIndex(int index); -extern std::vector NonShopItems; +extern std::map NonShopItems; diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 1fa01cdd7bd..5ec183b50a1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -40,7 +40,7 @@ json jsonData; std::map hintedLocations; extern std::array hintCategoryNames; -extern Area* GetHintRegion(uint32_t); +extern Region* GetHintRegion(uint32_t); namespace { std::string placementtxt; @@ -85,9 +85,9 @@ void WriteIngameSpoilerLog() { uint16_t spoilerItemIndex = 0; uint32_t spoilerStringOffset = 0; uint16_t spoilerSphereItemoffset = 0; - uint16_t spoilerGroupOffset = 0; - // Intentionally junk value so we trigger the 'new group, record some stuff' code - uint8_t currentGroup = SpoilerCollectionCheckGroup::SPOILER_COLLECTION_GROUP_COUNT; + uint16_t spoilerAreaOffset = 0; + // Intentionally junk value so we trigger the 'new area, record some stuff' code + RandomizerCheckArea currentArea = RandomizerCheckArea::RCAREA_INVALID; bool spoilerOutOfSpace = false; // Create map of string data offsets for all _unique_ item locations and names in the playthrough @@ -99,12 +99,12 @@ void WriteIngameSpoilerLog() { stringOffsetMap; // Map of strings to their offset into spoiler string data array stringOffsetMap.reserve(ctx->allLocations.size() * 2); - // Sort all locations by their group, so the in-game log can show a group of items by simply starting/ending at + // Sort all locations by their area, so the in-game log can show a area of items by simply starting/ending at // certain indices std::stable_sort(ctx->allLocations.begin(), ctx->allLocations.end(), [](const RandomizerCheck& a, const RandomizerCheck& b) { - auto groupA = Rando::StaticData::GetLocation(a)->GetCollectionCheckGroup(); - auto groupB = Rando::StaticData::GetLocation(b)->GetCollectionCheckGroup(); - return groupA < groupB; + RandomizerCheckArea areaA = Rando::StaticData::GetLocation(a)->GetArea(); + RandomizerCheckArea areaB = Rando::StaticData::GetLocation(b)->GetArea(); + return areaA < areaB; }); for (const RandomizerCheck key : ctx->allLocations) { @@ -116,30 +116,29 @@ void WriteIngameSpoilerLog() { // continue; // } // Beehives - if (!ctx->GetOption(RSK_SHUFFLE_BEEHIVES) && loc->IsCategory(Category::cBeehive)) { + if (!ctx->GetOption(RSK_SHUFFLE_BEEHIVES) && loc->GetRCType() == RCTYPE_BEEHIVE) { continue; } // Cows - else if (!ctx->GetOption(RSK_SHUFFLE_COWS) && loc->IsCategory(Category::cCow)) { + else if (!ctx->GetOption(RSK_SHUFFLE_COWS) && loc->GetRCType() == RCTYPE_COW) { continue; } // Merchants - else if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_OFF) && loc->IsCategory(Category::cMerchant)) { + else if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_OFF) && loc->GetRCType() == RCTYPE_MERCHANT) { continue; } // Adult Trade - else if (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && loc->IsCategory(Category::cAdultTrade)) { + else if (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && loc->GetRCType() == RCTYPE_ADULT_TRADE) { continue; } // Chest Minigame - else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_GENERIC_OFF) && - loc->IsCategory(Category::cChestMinigame)) { + else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_GENERIC_OFF) && loc->GetRCType() == RCTYPE_CHEST_GAME) { continue; } // Gerudo Fortress else if ((ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && - (loc->IsCategory(Category::cVanillaGFSmallKey) || loc->GetHintKey() == RHT_GF_GERUDO_MEMBERSHIP_CARD)) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && loc->IsCategory(Category::cVanillaGFSmallKey) && + (loc->GetRCType() == RCTYPE_GF_KEY || loc->GetHintKey() == RHT_GF_GERUDO_MEMBERSHIP_CARD)) || + (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && loc->GetRCType() == RCTYPE_GF_KEY && loc->GetHintKey() != RHT_GF_NORTH_F1_CARPENTER)) { continue; } @@ -160,8 +159,8 @@ void WriteIngameSpoilerLog() { } // PURPLE TODO: LOCALIZATION auto locItem = itemLocation->GetPlacedItemName().GetEnglish(); - if (itemLocation->GetPlacedRandomizerGet() == RG_ICE_TRAP && loc->IsCategory(Category::cShop)) { - locItem = NonShopItems[TransformShopIndex(GetShopIndex(key))].Name.GetEnglish(); + if (itemLocation->GetPlacedRandomizerGet() == RG_ICE_TRAP && loc->GetRCType() == RCTYPE_SHOP) { + locItem = NonShopItems[key].Name.GetEnglish(); } if (stringOffsetMap.find(locItem) == stringOffsetMap.end()) { if (spoilerStringOffset + locItem.size() + 1 >= SPOILER_STRING_DATA_SIZE) { @@ -201,29 +200,37 @@ void WriteIngameSpoilerLog() { } } // Gold Skulltulas - else if (loc->IsCategory(Category::cSkulltula) && + else if (loc->GetRCType() == RCTYPE_SKULL_TOKEN && ((ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) || (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS) && !loc->IsDungeon()) || (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD) && loc->IsDungeon()))) { spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS; } // Deku Scrubs - else if (loc->IsCategory(Category::cDekuScrub) && !loc->IsCategory(Category::cDekuScrubUpgrades) && - ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)) { + else if ( + loc->GetRCType() == RCTYPE_SCRUB && + // these 3 scrubs are always randomized + !( + loc->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || + loc->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || + loc->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO + ) && + ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) + ) { spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE; spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS; } - auto checkGroup = loc->GetCollectionCheckGroup(); - spoilerData.ItemLocations[spoilerItemIndex].Group = checkGroup; + RandomizerCheckArea checkArea = loc->GetArea(); + spoilerData.ItemLocations[spoilerItemIndex].Area = checkArea; - // Group setup - if (checkGroup != currentGroup) { - currentGroup = checkGroup; - spoilerData.GroupOffsets[currentGroup] = spoilerGroupOffset; + // Area setup + if (checkArea != currentArea) { + currentArea = checkArea; + spoilerData.AreaOffsets[currentArea] = spoilerAreaOffset; } - ++spoilerData.GroupItemCounts[currentGroup]; - ++spoilerGroupOffset; + ++spoilerData.AreaItemCounts[currentArea]; + ++spoilerAreaOffset; itemLocationsMap[key] = spoilerItemIndex++; } @@ -287,7 +294,7 @@ static void WriteLocation( // // Insert a padding so we get a kind of table in the XML document. // int16_t requiredPadding = LONGEST_NAME - location->GetName().length(); - // if (location->IsCategory(Category::cShop)) { + // if (location->GetRCType() == RCTYPE_SHOP) { // // Shop items have short location names, but come with an additional price attribute. // requiredPadding -= PRICE_ATTRIBUTE; // } @@ -297,7 +304,7 @@ static void WriteLocation( // } // } - // if (location->IsCategory(Category::cShop)) { + // if (location->GetRCType() == RCTYPE_SHOP) { // char price[6]; // sprintf(price, "%03d", location->GetPrice()); // node->SetAttribute("price", price); @@ -608,6 +615,8 @@ const char* SpoilerLog_Write() { jsonData.clear(); jsonData["version"] = (char*) gBuildVersion; + jsonData["git_branch"] = (char*) gGitBranch; + jsonData["git_commit"] = (char*) gGitCommitHash; jsonData["seed"] = ctx->GetSettings()->GetSeedString(); jsonData["finalSeed"] = ctx->GetSettings()->GetSeed(); diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp index 89b9d36bc61..bf2fd9f6054 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.hpp @@ -11,53 +11,16 @@ using RandomizerHash = std::array; typedef enum { SPOILER_CHK_NONE, - SPOILER_CHK_ALWAYS_COLLECTED, SPOILER_CHK_CHEST, SPOILER_CHK_COLLECTABLE, SPOILER_CHK_GOLD_SKULLTULA, SPOILER_CHK_ITEM_GET_INF, SPOILER_CHK_EVENT_CHK_INF, SPOILER_CHK_INF_TABLE, - SPOILER_CHK_FISH, - SPOILER_CHK_MINIGAME, - SPOILER_CHK_POE_POINTS, - SPOILER_CHK_SHOP_ITEM, - SPOILER_CHK_MASTER_SWORD, SPOILER_CHK_GRAVEDIGGER, SPOILER_CHK_RANDOMIZER_INF, } SpoilerCollectionCheckType; -// GetLocation groups for checks, used to group the checks by logical location -typedef enum { - GROUP_NO_GROUP, - GROUP_KOKIRI_FOREST, // 0x55, 0x28 - GROUP_LOST_WOODS, // 0x5B, 0x56 - GROUP_DUNGEON_DEKU_TREE, // 0x00, 0x11 - GROUP_DUNGEON_FOREST_TEMPLE, // 0x03 - GROUP_KAKARIKO, // 0x37, 0x42, 0x3F, 0x40, 0x41, 0x48, 0x52, 0x53 - GROUP_DUNGEON_BOTTOM_OF_THE_WELL, // 0x08 - GROUP_DUNGEON_SHADOW_TEMPLE, // 0x07 - GROUP_DEATH_MOUNTAIN, // 0x60, 0x61 - GROUP_GORON_CITY, // 0x62 - GROUP_DUNGEON_DODONGOS_CAVERN, // 0x01, 0x12 - GROUP_DUNGEON_FIRE_TEMPLE, // 0x04 - GROUP_ZORAS_RIVER, // 0x54 - GROUP_ZORAS_DOMAIN, // 0x58, 0x59 - GROUP_DUNGEON_JABUJABUS_BELLY, // 0x02, 0x13 - GROUP_DUNGEON_ICE_CAVERN, // 0x09 - GROUP_HYRULE_FIELD, // 0x51 - GROUP_LON_LON_RANCH, // 0x4C - GROUP_LAKE_HYLIA, // 0x57 - GROUP_DUNGEON_WATER_TEMPLE, // 0x05 - GROUP_GERUDO_VALLEY, // 0x5A, 0x5D, 0x0C, 0x5E, 0x5C - GROUP_GERUDO_TRAINING_GROUND, // 0x0B - GROUP_DUNGEON_SPIRIT_TEMPLE, // 0x06 - GROUP_HYRULE_CASTLE, // 0x10, 0x4B, 0x35, 0x42, 0x4D, 0x5F, 0x4A - GROUP_DUNGEON_GANONS_CASTLE, // 0x0A, 0x0D, 0x0E, 0x0F - SPOILER_COLLECTION_GROUP_COUNT, - // Grottos are all 0x3E -} SpoilerCollectionCheckGroup; - typedef enum { COLLECTTYPE_NORMAL, COLLECTTYPE_REPEATABLE, @@ -82,7 +45,7 @@ typedef struct { SpoilerCollectionCheckType CollectionCheckType; uint8_t LocationScene; uint8_t LocationFlag; - SpoilerCollectionCheckGroup Group; + RandomizerCheckArea Area; SpoilerItemCollectType CollectType; SpoilerItemRevealType RevealType; } SpoilerItemLocation; @@ -99,8 +62,8 @@ typedef struct { SpoilerItemLocation ItemLocations[SPOILER_ITEMS_MAX]; uint16_t SphereItemLocations[SPOILER_ITEMS_MAX]; char StringData[SPOILER_STRING_DATA_SIZE]; - uint16_t GroupItemCounts[SPOILER_COLLECTION_GROUP_COUNT]; - uint16_t GroupOffsets[SPOILER_COLLECTION_GROUP_COUNT]; + uint16_t AreaItemCounts[RCAREA_INVALID]; + uint16_t AreaOffsets[RCAREA_INVALID]; } SpoilerData; void GenerateHash(); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index db348b32f82..18f187c4dd1 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -105,10 +105,9 @@ void Context::PlaceItemInLocation(const RandomizerCheck locKey, const Randomizer // If we're placing a non-shop item in a shop location, we want to record it for custom messages if (StaticData::RetrieveItem(item).GetItemType() != ITEMTYPE_SHOP && - StaticData::GetLocation(locKey)->IsCategory(Category::cShop)) { - const int index = TransformShopIndex(GetShopIndex(locKey)); - NonShopItems[index].Name = StaticData::RetrieveItem(item).GetName(); - NonShopItems[index].Repurchaseable = + StaticData::GetLocation(locKey)->GetRCType() == RCTYPE_SHOP) { + NonShopItems[locKey].Name = StaticData::RetrieveItem(item).GetName(); + NonShopItems[locKey].Repurchaseable = StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_REFILL || StaticData::RetrieveItem(item).GetHintKey() == RHT_PROGRESSIVE_BOMBCHUS; } @@ -136,11 +135,11 @@ void Context::AddLocations(const Container& locations, std::vectorGetOption(RSK_TRIFORCE_HUNT)) { AddLocation(RC_TRIFORCE_COMPLETED); } - AddLocations(StaticData::overworldLocations); + AddLocations(StaticData::GetOverworldLocations()); if (mSettings->GetOption(RSK_FISHSANITY).IsNot(RO_FISHSANITY_OFF)) { AddLocations(mFishsanity->GetFishsanityLocations().first); @@ -152,7 +151,7 @@ void Context::GenerateLocationPool() { } void Context::AddExcludedOptions() { - AddLocations(StaticData::overworldLocations, &everyPossibleLocation); + AddLocations(StaticData::GetOverworldLocations(), &everyPossibleLocation); for (const auto dungeon : mDungeons->GetDungeonList()) { AddLocations(dungeon->GetEveryLocation(), &everyPossibleLocation); } @@ -161,16 +160,14 @@ void Context::AddExcludedOptions() { } } -std::vector Context::GetLocations(const std::vector& locationPool, - const Category categoryInclude, const Category categoryExclude) { - std::vector locationsInCategory; +std::vector Context::GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType) { + std::vector locationsOfType; for (RandomizerCheck locKey : locationPool) { - if (StaticData::GetLocation(locKey)->IsCategory(categoryInclude) && - !StaticData::GetLocation(locKey)->IsCategory(categoryExclude)) { - locationsInCategory.push_back(locKey); + if (StaticData::GetLocation(locKey)->GetRCType() == checkType) { + locationsOfType.push_back(locKey); } } - return locationsInCategory; + return locationsOfType; } void Context::ClearItemLocations() { @@ -190,25 +187,13 @@ void Context::ItemReset() { } void Context::LocationReset() { - for (const RandomizerCheck il : allLocations) { - GetItemLocation(il)->RemoveFromPool(); - } - - for (const RandomizerCheck il : StaticData::dungeonRewardLocations) { - GetItemLocation(il)->RemoveFromPool(); - } - - for (const RandomizerCheck il : StaticData::gossipStoneLocations) { - GetItemLocation(il)->RemoveFromPool(); - } - - for (const RandomizerCheck il : StaticData::staticHintLocations) { - GetItemLocation(il)->RemoveFromPool(); + for (auto& il : itemLocationTable) { + il.RemoveFromPool(); } } void Context::HintReset() { - for (const RandomizerCheck il : StaticData::gossipStoneLocations) { + for (const RandomizerCheck il : StaticData::GetGossipStoneLocations()) { GetItemLocation(il)->ResetVariables(); } for (Hint& hint : hintTable){ @@ -227,8 +212,8 @@ void Context::CreateItemOverrides() { iceTrapModels[locKey] = val.LooksLike(); val.SetTrickName(GetIceTrapName(val.LooksLike())); // If this is ice trap is in a shop, change the name based on what the model will look like - if (loc->IsCategory(Category::cShop)) { - NonShopItems[TransformShopIndex(GetShopIndex(locKey))].Name = val.GetTrickName(); + if (loc->GetRCType() == RCTYPE_SHOP) { + NonShopItems[locKey].Name = val.GetTrickName(); } overrides[locKey] = val; } @@ -395,498 +380,6 @@ void Context::ParseHintJson(nlohmann::json spoilerFileJson) { CreateStaticHints(); } -std::map Context::RandoGetToEquipFlag = { - { RG_KOKIRI_SWORD, EQUIP_FLAG_SWORD_KOKIRI }, - { RG_MASTER_SWORD, EQUIP_FLAG_SWORD_MASTER }, - { RG_BIGGORON_SWORD, EQUIP_FLAG_SWORD_BGS }, - { RG_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, - { RG_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, - { RG_MIRROR_SHIELD, EQUIP_FLAG_SHIELD_MIRROR }, - { RG_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, - { RG_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, - { RG_BUY_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, - { RG_BUY_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, - { RG_BUY_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, - { RG_BUY_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, - { RG_IRON_BOOTS, EQUIP_FLAG_BOOTS_IRON }, - { RG_HOVER_BOOTS, EQUIP_FLAG_BOOTS_HOVER } -}; - -std::map Context::RandoGetToRandInf = { - { RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER }, - { RG_WEIRD_EGG, RAND_INF_WEIRD_EGG }, - { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, - { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, - { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, - { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, - { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, - { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, - { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, - { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, - { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, - { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, - { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, - { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, - { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, - { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, - { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, - { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, - { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND } -}; - -std::map Context::RandoGetToDungeonScene = { - { RG_FOREST_TEMPLE_SMALL_KEY, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_SMALL_KEY, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_SMALL_KEY, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, - { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, - { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, - { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_KEY_RING, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUNDS_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, - { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, - { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, - { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_BOSS_KEY, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_BOSS_KEY, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_BOSS_KEY, SCENE_SHADOW_TEMPLE }, - { RG_GANONS_CASTLE_BOSS_KEY, SCENE_INSIDE_GANONS_CASTLE }, - { RG_DEKU_TREE_MAP, SCENE_DEKU_TREE }, - { RG_DODONGOS_CAVERN_MAP, SCENE_DODONGOS_CAVERN }, - { RG_JABU_JABUS_BELLY_MAP, SCENE_JABU_JABU }, - { RG_FOREST_TEMPLE_MAP, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_MAP, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_MAP, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_MAP, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_MAP, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_MAP, SCENE_BOTTOM_OF_THE_WELL }, - { RG_ICE_CAVERN_MAP, SCENE_ICE_CAVERN }, - { RG_DEKU_TREE_COMPASS, SCENE_DEKU_TREE }, - { RG_DODONGOS_CAVERN_COMPASS, SCENE_DODONGOS_CAVERN }, - { RG_JABU_JABUS_BELLY_COMPASS, SCENE_JABU_JABU }, - { RG_FOREST_TEMPLE_COMPASS, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_COMPASS, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_COMPASS, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_COMPASS, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_COMPASS, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_COMPASS, SCENE_BOTTOM_OF_THE_WELL }, - { RG_ICE_CAVERN_COMPASS, SCENE_ICE_CAVERN }, - { RG_TREASURE_GAME_SMALL_KEY, SCENE_TREASURE_BOX_SHOP } -}; - -std::map Context::RandoGetToQuestItem = { - { RG_FOREST_MEDALLION, QUEST_MEDALLION_FOREST }, - { RG_FIRE_MEDALLION, QUEST_MEDALLION_FIRE }, - { RG_WATER_MEDALLION, QUEST_MEDALLION_WATER }, - { RG_SPIRIT_MEDALLION, QUEST_MEDALLION_SPIRIT }, - { RG_SHADOW_MEDALLION, QUEST_MEDALLION_SHADOW }, - { RG_LIGHT_MEDALLION, QUEST_MEDALLION_LIGHT }, - { RG_MINUET_OF_FOREST, QUEST_SONG_MINUET }, - { RG_BOLERO_OF_FIRE, QUEST_SONG_BOLERO }, - { RG_SERENADE_OF_WATER, QUEST_SONG_SERENADE }, - { RG_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM }, - { RG_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE }, - { RG_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE }, - { RG_ZELDAS_LULLABY, QUEST_SONG_LULLABY }, - { RG_EPONAS_SONG, QUEST_SONG_EPONA }, - { RG_SARIAS_SONG, QUEST_SONG_SARIA }, - { RG_SUNS_SONG, QUEST_SONG_SUN }, - { RG_SONG_OF_TIME, QUEST_SONG_TIME }, - { RG_SONG_OF_STORMS, QUEST_SONG_STORMS }, - { RG_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, - { RG_GORON_RUBY, QUEST_GORON_RUBY }, - { RG_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, - { RG_STONE_OF_AGONY, QUEST_STONE_OF_AGONY }, - { RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD }, -}; - -uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT }; -uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME }; - -void Context::ApplyItemEffect(Item& item, bool state) { - auto randoGet = item.GetRandomizerGet(); - if (item.GetGIEntry()->objectId == OBJECT_GI_STICK) { - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - } - if (item.GetGIEntry()->objectId == OBJECT_GI_NUTS) { - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - } - switch (item.GetItemType()) { - case ITEMTYPE_ITEM: - { - switch (randoGet) { - case RG_STONE_OF_AGONY: - case RG_GERUDO_MEMBERSHIP_CARD: - SetQuestItem(RandoGetToQuestItem.at(randoGet), state); - break; - case RG_WEIRD_EGG: - SetRandoInf(RAND_INF_WEIRD_EGG, state); - break; - case RG_ZELDAS_LETTER: - SetRandoInf(RAND_INF_ZELDAS_LETTER, state); - break; - case RG_DOUBLE_DEFENSE: - mSaveContext->isDoubleDefenseAcquired = state; - break; - case RG_POCKET_EGG: - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - SetAdultTrade(item.GetGIEntry()->itemId, state); - break; - case RG_PROGRESSIVE_HOOKSHOT: - { - uint8_t i; - for (i = 0; i < 3; i++) { - if (CurrentInventory(ITEM_HOOKSHOT) == HookshotLookup[i]) { - break; - } - } - auto newItem = i + (!state ? -1 : 1); - if (newItem < 0) { - newItem = 0; - } - else if (newItem > 2) { - newItem = 2; - } - SetInventory(ITEM_HOOKSHOT, HookshotLookup[newItem]); - } break; - case RG_PROGRESSIVE_STRENGTH: - { - auto currentLevel = CurrentUpgrade(UPG_STRENGTH); - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_STRENGTH, newLevel); - } break; - case RG_PROGRESSIVE_BOMB_BAG: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BOMB_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BOMB_BAG, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_BOMB_BAG); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_BOMB, (!state ? ITEM_NONE : ITEM_BOMB)); - } - SetUpgrade(UPG_BOMB_BAG, newLevel); - } break; - case RG_PROGRESSIVE_BOW: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_QUIVER_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_QUIVER, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_QUIVER); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_BOW, (!state ? ITEM_NONE : ITEM_BOW)); - } - SetUpgrade(UPG_QUIVER, newLevel); - } break; - case RG_PROGRESSIVE_SLINGSHOT: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BULLET_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BULLET_BAG, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_BULLET_BAG); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_SLINGSHOT, (!state ? ITEM_NONE : ITEM_SLINGSHOT)); - } - SetUpgrade(UPG_BULLET_BAG, newLevel); - } break; - case RG_PROGRESSIVE_WALLET: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_WALLET_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_MONEY, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_WALLET); - if (!CheckRandoInf(RAND_INF_HAS_WALLET) && state) { - SetRandoInf(RAND_INF_HAS_WALLET, true); - } - else if (currentLevel == 0 && !state) { - SetRandoInf(RAND_INF_HAS_WALLET, false); - } - else { - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_WALLET, newLevel); - } - } break; - case RG_PROGRESSIVE_SCALE: - { - auto currentLevel = CurrentUpgrade(UPG_SCALE); - if (!CheckRandoInf(RAND_INF_CAN_SWIM) && state) { - SetRandoInf(RAND_INF_CAN_SWIM, true); - } - else if (currentLevel == 0 && !state) { - SetRandoInf(RAND_INF_CAN_SWIM, false); - } - else { - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_SCALE, newLevel); - } - } break; - case RG_PROGRESSIVE_NUT_UPGRADE: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_NUT_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_NUTS); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - } - SetUpgrade(UPG_NUTS, newLevel); - } break; - case RG_PROGRESSIVE_STICK_UPGRADE: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_STICK_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_STICKS); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - } - SetUpgrade(UPG_STICKS, newLevel); - } break; - case RG_PROGRESSIVE_BOMBCHUS: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BOMBCHU_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BOMBCHUS, true); - break; - } - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - } break; - case RG_PROGRESSIVE_MAGIC_METER: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_MAGIC_METER, true); - break; - } - mSaveContext->magicLevel += (!state ? -1 : 1); - } break; - case RG_PROGRESSIVE_OCARINA: - { - uint8_t i; - for (i = 0; i < 3; i++) { - if (CurrentInventory(ITEM_OCARINA_FAIRY) == OcarinaLookup[i]) { - break; - } - } - i += (!state ? -1 : 1); - if (i < 0) { - i = 0; - } - else if (i > 2) { - i = 2; - } - SetInventory(ITEM_OCARINA_FAIRY, OcarinaLookup[i]); - } break; - case RG_HEART_CONTAINER: - mSaveContext->healthCapacity += (!state ? -16 : 16); - break; - case RG_PIECE_OF_HEART: - mSaveContext->healthCapacity += (!state ? -4 : 4); - break; - case RG_BOOMERANG: - case RG_LENS_OF_TRUTH: - case RG_MEGATON_HAMMER: - case RG_DINS_FIRE: - case RG_FARORES_WIND: - case RG_NAYRUS_LOVE: - case RG_FIRE_ARROWS: - case RG_ICE_ARROWS: - case RG_LIGHT_ARROWS: - SetInventory(item.GetGIEntry()->itemId, (!state ? ITEM_NONE : item.GetGIEntry()->itemId)); - break; - case RG_MAGIC_BEAN: - case RG_MAGIC_BEAN_PACK: - { - auto change = (item.GetRandomizerGet() == RG_MAGIC_BEAN ? 1 : 10); - auto current = GetAmmo(ITEM_BEAN); - SetAmmo(ITEM_BEAN, current + (!state ? -change : change)); - } break; - case RG_EMPTY_BOTTLE: - case RG_BOTTLE_WITH_MILK: - case RG_BOTTLE_WITH_RED_POTION: - case RG_BOTTLE_WITH_GREEN_POTION: - case RG_BOTTLE_WITH_BLUE_POTION: - case RG_BOTTLE_WITH_FAIRY: - case RG_BOTTLE_WITH_FISH: - case RG_BOTTLE_WITH_BLUE_FIRE: - case RG_BOTTLE_WITH_BUGS: - case RG_BOTTLE_WITH_POE: - case RG_BOTTLE_WITH_BIG_POE: - { - uint8_t slot = SLOT_BOTTLE_1; - while (slot != SLOT_BOTTLE_4) { - if (mSaveContext->inventory.items[slot] == ITEM_NONE) { - break; - } - slot++; - } - mSaveContext->inventory.items[slot] = item.GetGIEntry()->itemId; - } break; - case RG_RUTOS_LETTER: - SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state); - break; - case RG_GOHMA_SOUL: - case RG_KING_DODONGO_SOUL: - case RG_BARINADE_SOUL: - case RG_PHANTOM_GANON_SOUL: - case RG_VOLVAGIA_SOUL: - case RG_MORPHA_SOUL: - case RG_BONGO_BONGO_SOUL: - case RG_TWINROVA_SOUL: - case RG_GANON_SOUL: - case RG_OCARINA_A_BUTTON: - case RG_OCARINA_C_UP_BUTTON: - case RG_OCARINA_C_DOWN_BUTTON: - case RG_OCARINA_C_LEFT_BUTTON: - case RG_OCARINA_C_RIGHT_BUTTON: - case RG_GREG_RUPEE: - case RG_FISHING_POLE: - SetRandoInf(RandoGetToRandInf.at(randoGet), state); - break; - case RG_TRIFORCE_PIECE: - mSaveContext->triforcePiecesCollected += (!state ? -1 : 1); - break; - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - break; - } - } - break; - case ITEMTYPE_EQUIP: - { - RandomizerGet itemRG = item.GetRandomizerGet(); - if (itemRG == RG_GIANTS_KNIFE) { - return; - } - uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second; - if (!state) { - mSaveContext->inventory.equipment &= ~equipId; - if (equipId == EQUIP_FLAG_SWORD_BGS) { - mSaveContext->bgsFlag = false; - } - } - else { - mSaveContext->inventory.equipment |= equipId; - if (equipId == EQUIP_FLAG_SWORD_BGS) { - mSaveContext->bgsFlag = true; - } - } - } - break; - case ITEMTYPE_DUNGEONREWARD: - case ITEMTYPE_SONG: - SetQuestItem(RandoGetToQuestItem.find(item.GetRandomizerGet())->second, state); - break; - case ITEMTYPE_MAP: - SetDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); - break; - case ITEMTYPE_COMPASS: - SetDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); - break; - case ITEMTYPE_BOSSKEY: - SetDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); - break; - case ITEMTYPE_FORTRESS_SMALLKEY: - case ITEMTYPE_SMALLKEY: - { - auto randoGet = item.GetRandomizerGet(); - auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; - auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; - auto count = GetSmallKeyCount(dungeonIndex); - if (!state) { - if (keyring) { - count = 0; - } - else { - count -= 1; - } - } - else { - if (keyring) { - count = 10; - } - else { - count += 1; - } - } - SetSmallKeyCount(dungeonIndex, count); - } break; - case ITEMTYPE_TOKEN: - mSaveContext->inventory.gsTokens += (!state ? -1 : 1); - break; - case ITEMTYPE_EVENT: - break; - case ITEMTYPE_DROP: - case ITEMTYPE_REFILL: - case ITEMTYPE_SHOP: - { - RandomizerGet itemRG = item.GetRandomizerGet(); - if (itemRG == RG_BUY_HYLIAN_SHIELD || itemRG == RG_BUY_DEKU_SHIELD || itemRG == RG_BUY_GORON_TUNIC || itemRG == RG_BUY_ZORA_TUNIC) { - uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second; - if (!state) { - mSaveContext->inventory.equipment &= ~equipId; - } - else { - mSaveContext->inventory.equipment |= equipId; - } - } - switch (itemRG) { - case RG_DEKU_NUTS_5: - case RG_DEKU_NUTS_10: - case RG_BUY_DEKU_NUTS_5: - case RG_BUY_DEKU_NUTS_10: - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - break; - case RG_DEKU_STICK_1: - case RG_BUY_DEKU_STICK_1: - case RG_STICKS: - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - break; - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - break; - } - } break; - } - mLogic->UpdateHelpers(); -} - std::shared_ptr Context::GetSettings() { return mSettings; } @@ -914,173 +407,6 @@ std::shared_ptr Context::GetLogic() { return mLogic; } -SaveContext* Context::GetSaveContext() { - if (mSaveContext == nullptr) { - NewSaveContext(); - } - return mSaveContext; -} - -void Context::SetSaveContext(SaveContext* context) { - mSaveContext = context; -} - -void Context::InitSaveContext() { - mSaveContext->totalDays = 0; - mSaveContext->bgsDayCount = 0; - - mSaveContext->deaths = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->playerName); i++) { - mSaveContext->playerName[i] = 0x3E; - } - mSaveContext->n64ddFlag = 0; - mSaveContext->healthCapacity = 0x30; - mSaveContext->health = 0x30; - mSaveContext->magicLevel = 0; - mSaveContext->magic = 0x30; - mSaveContext->rupees = 0; - mSaveContext->swordHealth = 0; - mSaveContext->naviTimer = 0; - mSaveContext->isMagicAcquired = 0; - mSaveContext->isDoubleMagicAcquired = 0; - mSaveContext->isDoubleDefenseAcquired = 0; - mSaveContext->bgsFlag = 0; - mSaveContext->ocarinaGameRoundNum = 0; - for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.buttonItems); button++) { - mSaveContext->childEquips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.cButtonSlots); button++) { - mSaveContext->childEquips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->childEquips.equipment = 0; - for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.buttonItems); button++) { - mSaveContext->adultEquips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.cButtonSlots); button++) { - mSaveContext->adultEquips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->adultEquips.equipment = 0; - mSaveContext->unk_54 = 0; - mSaveContext->savedSceneNum = SCENE_LINKS_HOUSE; - - // Equipment - for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.buttonItems); button++) { - mSaveContext->equips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.cButtonSlots); button++) { - mSaveContext->equips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->equips.equipment = 0; - - // Inventory - for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) { - mSaveContext->inventory.items[item] = ITEM_NONE; - } - for (int ammo = 0; ammo < ARRAY_COUNT(mSaveContext->inventory.ammo); ammo++) { - mSaveContext->inventory.ammo[ammo] = 0; - } - mSaveContext->inventory.equipment = 0; - mSaveContext->inventory.upgrades = 0; - mSaveContext->inventory.questItems = 0; - for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) { - mSaveContext->inventory.dungeonItems[dungeon] = 0; - } - for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) { - mSaveContext->inventory.dungeonKeys[dungeon] = 0x0; - } - mSaveContext->inventory.defenseHearts = 0; - mSaveContext->inventory.gsTokens = 0; - for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) { - mSaveContext->sceneFlags[scene].chest = 0; - mSaveContext->sceneFlags[scene].swch = 0; - mSaveContext->sceneFlags[scene].clear = 0; - mSaveContext->sceneFlags[scene].collect = 0; - mSaveContext->sceneFlags[scene].unk = 0; - mSaveContext->sceneFlags[scene].rooms = 0; - mSaveContext->sceneFlags[scene].floors = 0; - } - mSaveContext->fw.pos.x = 0; - mSaveContext->fw.pos.y = 0; - mSaveContext->fw.pos.z = 0; - mSaveContext->fw.yaw = 0; - mSaveContext->fw.playerParams = 0; - mSaveContext->fw.entranceIndex = 0; - mSaveContext->fw.roomIndex = 0; - mSaveContext->fw.set = 0; - mSaveContext->fw.tempSwchFlags = 0; - mSaveContext->fw.tempCollectFlags = 0; - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->gsFlags); flag++) { - mSaveContext->gsFlags[flag] = 0; - } - for (int highscore = 0; highscore < ARRAY_COUNT(mSaveContext->highScores); highscore++) { - mSaveContext->highScores[highscore] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->eventChkInf); flag++) { - mSaveContext->eventChkInf[flag] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->itemGetInf); flag++) { - mSaveContext->itemGetInf[flag] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->infTable); flag++) { - mSaveContext->infTable[flag] = 0; - } - mSaveContext->worldMapAreaData = 0; - mSaveContext->scarecrowLongSongSet = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowLongSong); i++) { - mSaveContext->scarecrowLongSong[i].noteIdx = 0; - mSaveContext->scarecrowLongSong[i].unk_01 = 0; - mSaveContext->scarecrowLongSong[i].unk_02 = 0; - mSaveContext->scarecrowLongSong[i].volume = 0; - mSaveContext->scarecrowLongSong[i].vibrato = 0; - mSaveContext->scarecrowLongSong[i].tone = 0; - mSaveContext->scarecrowLongSong[i].semitone = 0; - } - mSaveContext->scarecrowSpawnSongSet = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowSpawnSong); i++) { - mSaveContext->scarecrowSpawnSong[i].noteIdx = 0; - mSaveContext->scarecrowSpawnSong[i].unk_01 = 0; - mSaveContext->scarecrowSpawnSong[i].unk_02 = 0; - mSaveContext->scarecrowSpawnSong[i].volume = 0; - mSaveContext->scarecrowSpawnSong[i].vibrato = 0; - mSaveContext->scarecrowSpawnSong[i].tone = 0; - mSaveContext->scarecrowSpawnSong[i].semitone = 0; - } - - mSaveContext->horseData.scene = SCENE_HYRULE_FIELD; - mSaveContext->horseData.pos.x = -1840; - mSaveContext->horseData.pos.y = 72; - mSaveContext->horseData.pos.z = 5497; - mSaveContext->horseData.angle = -0x6AD9; - mSaveContext->magicLevel = 0; - mSaveContext->infTable[29] = 1; - mSaveContext->sceneFlags[5].swch = 0x40000000; - - // SoH specific - mSaveContext->backupFW = mSaveContext->fw; - mSaveContext->pendingSale = ITEM_NONE; - mSaveContext->pendingSaleMod = MOD_NONE; - mSaveContext->isBossRushPaused = 0; - mSaveContext->pendingIceTrapCount = 0; - - // Init with normal quest unless only an MQ rom is provided - mSaveContext->questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER; - - //RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT) -} - -void Context::NewSaveContext() { - if (mSaveContext != nullptr && mSaveContext != &gSaveContext) { - free(mSaveContext); - } - mSaveContext = new SaveContext(); - InitSaveContext(); -} - -void Context::ResetLogic() { - NewSaveContext(); - mLogic->Reset(); -} - std::shared_ptr Context::GetTrials() { return mTrials; } @@ -1105,120 +431,4 @@ TrickOption& Context::GetTrickOption(const RandomizerTrick key) const { return mSettings->GetTrickOption(key); } -uint8_t Context::InventorySlot(uint32_t item) { - return gItemSlots[item]; -} - -uint32_t Context::CurrentUpgrade(uint32_t upgrade) { - return (mSaveContext->inventory.upgrades & gUpgradeMasks[upgrade]) >> gUpgradeShifts[upgrade]; -} - -uint32_t Context::CurrentInventory(uint32_t item) { - return mSaveContext->inventory.items[InventorySlot(item)]; -} - -void Context::SetUpgrade(uint32_t upgrade, uint8_t level) { - mSaveContext->inventory.upgrades &= gUpgradeNegMasks[upgrade]; - mSaveContext->inventory.upgrades |= level << gUpgradeShifts[upgrade]; -} - -bool Context::CheckInventory(uint32_t item, bool exact) { - auto current = mSaveContext->inventory.items[InventorySlot(item)]; - return exact ? (current == item) : (current != ITEM_NONE); -} - -void Context::SetInventory(uint32_t itemSlot, uint32_t item) { - mSaveContext->inventory.items[InventorySlot(itemSlot)] = item; -} - -bool Context::CheckEquipment(uint32_t equipFlag) { - return (equipFlag & mSaveContext->inventory.equipment); -} - -bool Context::CheckQuestItem(uint32_t item) { - return ((1 << item) & mSaveContext->inventory.questItems); -} - -bool Context::HasAdultTrade(uint32_t itemID) { - int tradeIndex = itemID - ITEM_POCKET_EGG; - return mSaveContext->adultTradeItems & (1 << tradeIndex); -} - -void Context::SetAdultTrade(uint32_t itemID, bool state) { - int tradeIndex = itemID - ITEM_POCKET_EGG; - if (!state) { - mSaveContext->adultTradeItems &= ~(1 << tradeIndex); - } - else { - mSaveContext->adultTradeItems |= (1 << tradeIndex); - } -} - -void Context::SetQuestItem(uint32_t item, bool state) { - if (!state) { - mSaveContext->inventory.questItems &= ~(1 << item); - } - else { - mSaveContext->inventory.questItems |= (1 << item); - } -} - -uint8_t Context::GetSmallKeyCount(uint32_t dungeonIndex) { - return mSaveContext->inventory.dungeonKeys[dungeonIndex]; -} - -void Context::SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count) { - mSaveContext->inventory.dungeonKeys[dungeonIndex] = count; -} - -bool Context::CheckDungeonItem(uint32_t item, uint32_t dungeonIndex) { - return mSaveContext->inventory.dungeonItems[dungeonIndex] & gBitFlags[item]; -} - -void Context::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { - if (!state) { - mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; - } - else { - mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; - } -} - -bool Context::CheckRandoInf(uint32_t flag) { - return mSaveContext->randomizerInf[flag >> 4] & (1 << (flag & 0xF)); -} - -void Context::SetRandoInf(uint32_t flag, bool state) { - if (!state) { - mSaveContext->randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } - else { - mSaveContext->randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); - } -} - -bool Context::CheckEventChkInf(int32_t flag) { - return mSaveContext->eventChkInf[flag >> 4] & (1 << (flag & 0xF)); -} - -void Context::SetEventChkInf(int32_t flag, bool state) { - if (!state) { - mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } - else { - mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); - } -} - -uint8_t Context::GetGSCount() { - return mSaveContext->inventory.gsTokens; -} - -uint8_t Context::GetAmmo(uint32_t item) { - return mSaveContext->inventory.ammo[gItemSlots[item]]; -} - -void Context::SetAmmo(uint32_t item, uint8_t count) { - mSaveContext->inventory.ammo[gItemSlots[item]] = count; -} } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/context.h b/soh/soh/Enhancements/randomizer/context.h index 13147143eb9..a1a7d0d5451 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -50,12 +50,7 @@ class Context { template void AddLocations(const Container& locations, std::vector* destination = nullptr); void GenerateLocationPool(); - static std::vector GetLocations(const std::vector& locationPool, - Category categoryInclude, Category categoryExclude = Category::cNull); - static std::map RandoGetToQuestItem; - static std::map RandoGetToDungeonScene; - static std::map RandoGetToEquipFlag; - static std::map RandoGetToRandInf; + static std::vector GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType); void AddExcludedOptions(); void LocationReset(); void ClearItemLocations(); @@ -68,18 +63,12 @@ class Context { void SetSpoilerLoaded(bool spoilerLoaded = true); bool IsPlandoLoaded() const; void SetPlandoLoaded(bool plandoLoaded = true); - void ApplyItemEffect(Item& item, bool state); std::shared_ptr GetSettings(); std::shared_ptr GetEntranceShuffler(); std::shared_ptr GetDungeons(); std::shared_ptr GetFishsanity(); DungeonInfo* GetDungeon(size_t key) const; std::shared_ptr GetLogic(); - SaveContext* GetSaveContext(); - void SetSaveContext(SaveContext* context); - void InitSaveContext(); - void NewSaveContext(); - void ResetLogic(); std::shared_ptr GetTrials(); TrialInfo* GetTrial(size_t key) const; TrialInfo* GetTrial(TrialKey key) const; @@ -101,28 +90,6 @@ class Context { bool playthroughBeatable = false; bool allLocationsReachable = false; RandomizerArea GetAreaFromString(std::string str); - uint8_t InventorySlot(uint32_t item); - void SetUpgrade(uint32_t upgrade, uint8_t level); - uint32_t CurrentUpgrade(uint32_t upgrade); - uint32_t CurrentInventory(uint32_t item); - bool CheckInventory(uint32_t item, bool exact); - void SetInventory(uint32_t itemSlot, uint32_t item); - bool CheckEquipment(uint32_t item); - bool CheckQuestItem(uint32_t item); - void SetQuestItem(uint32_t item, bool state); - bool HasAdultTrade(uint32_t item); - void SetAdultTrade(uint32_t item, bool state); - uint8_t GetSmallKeyCount(uint32_t dungeonIndex); - void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count); - bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex); - void SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state); - bool CheckRandoInf(uint32_t flag); - void SetRandoInf(uint32_t flag, bool state); - bool CheckEventChkInf(int32_t flag); - uint8_t GetGSCount(); - void SetEventChkInf(int32_t flag, bool state); - uint8_t GetAmmo(uint32_t item); - void SetAmmo(uint32_t item, uint8_t count); private: static std::weak_ptr mContext; @@ -132,7 +99,6 @@ class Context { std::shared_ptr mEntranceShuffler; std::shared_ptr mDungeons; std::shared_ptr mLogic; - SaveContext* mSaveContext = nullptr; std::shared_ptr mTrials; std::shared_ptr mFishsanity; bool mSeedGenerated = false; diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index 0f799b03646..8484288a572 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -100,7 +100,7 @@ void DungeonInfo::PlaceVanillaMap() const { auto dungeonLocations = GetDungeonLocations(); const auto mapLocation = FilterFromPool(dungeonLocations, [](const RandomizerCheck loc) { - return StaticData::GetLocation(loc)->IsCategory(Category::cVanillaMap); + return StaticData::GetLocation(loc)->GetRCType() == RCTYPE_MAP; })[0]; Context::GetInstance()->PlaceItemInLocation(mapLocation, map); } @@ -112,7 +112,7 @@ void DungeonInfo::PlaceVanillaCompass() const { auto dungeonLocations = GetDungeonLocations(); const auto compassLocation = FilterFromPool(dungeonLocations, [](const RandomizerCheck loc) { - return StaticData::GetLocation(loc)->IsCategory(Category::cVanillaCompass); + return StaticData::GetLocation(loc)->GetRCType() == RCTYPE_COMPASS; })[0]; Context::GetInstance()->PlaceItemInLocation(compassLocation, compass); } @@ -124,7 +124,7 @@ void DungeonInfo::PlaceVanillaBossKey() const { auto dungeonLocations = GetDungeonLocations(); const auto bossKeyLocation = FilterFromPool(dungeonLocations, [](const RandomizerCheck loc) { - return StaticData::GetLocation(loc)->IsCategory(Category::cVanillaBossKey); + return StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_KEY; })[0]; Context::GetInstance()->PlaceItemInLocation(bossKeyLocation, bossKey); } @@ -136,7 +136,7 @@ void DungeonInfo::PlaceVanillaSmallKeys() const { auto dungeonLocations = GetDungeonLocations(); const auto smallKeyLocations = FilterFromPool(dungeonLocations, [](const RandomizerCheck loc) { - return StaticData::GetLocation(loc)->IsCategory(Category::cVanillaSmallKey); + return StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SMALL_KEY; }); for (const auto location : smallKeyLocations) { Context::GetInstance()->PlaceItemInLocation(location, smallKey); diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 39eab139822..d0a887c3666 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -2,6 +2,7 @@ #include "3drando/pool_functions.hpp" #include "3drando/item_pool.hpp" +#include "../debugger/performanceTimer.h" #include @@ -38,12 +39,12 @@ bool Entrance::GetConditionsMet() const { } std::string Entrance::to_string() const { - return AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; + return RegionTable(parentRegion)->regionName + " -> " + RegionTable(connectedRegion)->regionName; } void Entrance::SetName(std::string name_) { if (name_ == "") { - name = AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; + name = RegionTable(parentRegion)->regionName + " -> " + RegionTable(connectedRegion)->regionName; } else { name = std::move(name_); } @@ -70,21 +71,24 @@ void Entrance::printAgeTimeAccess() { } bool Entrance::ConditionsMet(bool allAgeTimes) const { + auto ctx = Rando::Context::GetInstance(); + StartPerformanceTimer(PT_ENTRANCE_LOGIC); + Region* parent = RegionTable(parentRegion); + int conditionsMet = 0; - Area* parent = AreaTable(parentRegion); - int conditionsMet = 0; + if (allAgeTimes && !parent->AllAccess()) { + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + return false; + } - if (allAgeTimes && !parent->AllAccess()) { - return false; - } - - // check all possible day/night condition combinations - conditionsMet = (parent->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay, allAgeTimes)) + - (parent->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight, allAgeTimes)) + - (parent->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay, allAgeTimes)) + - (parent->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight, allAgeTimes)); + // check all possible day/night condition combinations + conditionsMet = (parent->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay, allAgeTimes)) + + (parent->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight, allAgeTimes)) + + (parent->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay, allAgeTimes)) + + (parent->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight, allAgeTimes)); - return conditionsMet && (!allAgeTimes || conditionsMet == 4); + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + return conditionsMet && (!allAgeTimes || conditionsMet == 4); } uint32_t Entrance::Getuint32_t() const { @@ -102,7 +106,6 @@ bool Entrance::CheckConditionAtAgeTime(bool& age, bool& time, bool passAnyway) c time = true; age = true; - logic->UpdateHelpers(); return GetConditionsMet() && (connectedRegion != RR_NONE || passAnyway); } @@ -114,8 +117,8 @@ RandomizerRegion Entrance::GetOriginalConnectedRegionKey() const { return originalConnectedRegion; } -Area* Entrance::GetConnectedRegion() const { - return AreaTable(connectedRegion); +Region* Entrance::GetConnectedRegion() const { + return RegionTable(connectedRegion); } void Entrance::SetParentRegion(RandomizerRegion newParent) { @@ -126,8 +129,8 @@ RandomizerRegion Entrance::GetParentRegionKey() const { return parentRegion; } -Area* Entrance::GetParentRegion() const { - return AreaTable(parentRegion); +Region* Entrance::GetParentRegion() const { + return RegionTable(parentRegion); } void Entrance::SetNewEntrance(RandomizerRegion newRegion) { @@ -204,11 +207,11 @@ Entrance* Entrance::GetReverse() const { void Entrance::Connect(RandomizerRegion newConnectedRegion) { connectedRegion = newConnectedRegion; - AreaTable(newConnectedRegion)->entrances.push_front(this); + RegionTable(newConnectedRegion)->entrances.push_front(this); } RandomizerRegion Entrance::Disconnect() { - AreaTable(connectedRegion)->entrances.remove_if([this](const auto entrance) { return this == entrance; }); + RegionTable(connectedRegion)->entrances.remove_if([this](const auto entrance) { return this == entrance; }); RandomizerRegion previouslyConnected = connectedRegion; connectedRegion = RR_NONE; return previouslyConnected; @@ -220,10 +223,10 @@ void Entrance::BindTwoWay(Entrance* otherEntrance) { } Entrance* Entrance::GetNewTarget() { - AreaTable(RR_ROOT)->AddExit(RR_ROOT, connectedRegion, [] { return true; }); - Entrance* targetEntrance = AreaTable(RR_ROOT)->GetExit(connectedRegion); + RegionTable(RR_ROOT)->AddExit(RR_ROOT, connectedRegion, [] { return true; }); + Entrance* targetEntrance = RegionTable(RR_ROOT)->GetExit(connectedRegion); targetEntrance->SetReplacement(this); - targetEntrance->SetName(AreaTable(RR_ROOT)->regionName + " -> " + GetConnectedRegion()->regionName); + targetEntrance->SetName(RegionTable(RR_ROOT)->regionName + " -> " + GetConnectedRegion()->regionName); return targetEntrance; } @@ -250,7 +253,7 @@ void EntranceShuffler::SetNoRandomEntrances(bool noRandomEntrances) { // Construct entrance name from parent and connected region keys std::string EntranceNameByRegions(RandomizerRegion parentRegion, RandomizerRegion connectedRegion) { - return AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; + return RegionTable(parentRegion)->regionName + " -> " + RegionTable(connectedRegion)->regionName; } void SetAllEntrancesData(std::vector& entranceShuffleTable) { @@ -261,7 +264,7 @@ void SetAllEntrancesData(std::vector& entranceShuffleTable) { auto& returnEntry = entrancePair.second; // set data - Entrance* forwardEntrance = AreaTable(forwardEntry.parentRegion)->GetExit(forwardEntry.connectedRegion); + Entrance* forwardEntrance = RegionTable(forwardEntry.parentRegion)->GetExit(forwardEntry.connectedRegion); forwardEntrance->SetIndex(forwardEntry.index); forwardEntrance->SetType(forwardEntry.type); forwardEntrance->SetAsPrimary(); @@ -272,7 +275,7 @@ void SetAllEntrancesData(std::vector& entranceShuffleTable) { } if (returnEntry.parentRegion != RR_NONE) { - Entrance* returnEntrance = AreaTable(returnEntry.parentRegion)->GetExit(returnEntry.connectedRegion); + Entrance* returnEntrance = RegionTable(returnEntry.parentRegion)->GetExit(returnEntry.connectedRegion); returnEntrance->SetIndex(returnEntry.index); returnEntrance->SetType(returnEntry.type); forwardEntrance->BindTwoWay(returnEntrance); @@ -462,7 +465,7 @@ static bool ValidateWorld(Entrance* entrancePlaced) { // Conditions will be checked during the search and any that fail will be figured out // afterwards ctx->GetLogic()->Reset(); - GetAccessibleLocations({}, SearchMode::ValidateWorld, RG_NONE, checkPoeCollectorAccess, checkOtherEntranceAccess); + ValidateEntrances(checkPoeCollectorAccess, checkOtherEntranceAccess); if (!ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) { // Unless entrances are decoupled, we don't want the player to end up through certain entrances as the wrong age @@ -541,24 +544,24 @@ static bool ValidateWorld(Entrance* entrancePlaced) { if (checkOtherEntranceAccess) { // At least one valid starting region with all basic refills should be reachable without using any items at // the beginning of the seed - if (!AreaTable(RR_KOKIRI_FOREST)->HasAccess() && !AreaTable(RR_KAKARIKO_VILLAGE)->HasAccess()) { + if (!RegionTable(RR_KOKIRI_FOREST)->HasAccess() && !RegionTable(RR_KAKARIKO_VILLAGE)->HasAccess()) { SPDLOG_DEBUG("Invalid starting area\n"); return false; } // Check that a region where time passes is always reachable as both ages without having collected any items - if (!Areas::HasTimePassAccess(RO_AGE_CHILD) || !Areas::HasTimePassAccess(RO_AGE_ADULT)) { + if (!Regions::HasTimePassAccess(RO_AGE_CHILD) || !Regions::HasTimePassAccess(RO_AGE_ADULT)) { SPDLOG_DEBUG("Time passing is not guaranteed as both ages\n"); return false; } // The player should be able to get back to ToT after going through time, without having collected any items // This is important to ensure that the player never loses access to the pedestal after going through time - if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && !AreaTable(RR_TEMPLE_OF_TIME)->Adult()) { + if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && !RegionTable(RR_TEMPLE_OF_TIME)->Adult()) { SPDLOG_DEBUG("Path to Temple of Time as adult is not guaranteed\n"); return false; } else if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && - !AreaTable(RR_TEMPLE_OF_TIME)->Child()) { + !RegionTable(RR_TEMPLE_OF_TIME)->Child()) { SPDLOG_DEBUG("Path to Temple of Time as child is not guaranteed\n"); return false; } @@ -568,7 +571,7 @@ static bool ValidateWorld(Entrance* entrancePlaced) { // This is important to ensure that players can never lock their only bottles by filling them with Big Poes they // can't sell if (checkPoeCollectorAccess) { - if (!AreaTable(RR_MARKET_GUARD_HOUSE)->Adult()) { + if (!RegionTable(RR_MARKET_GUARD_HOUSE)->Adult()) { SPDLOG_DEBUG("Big Poe Shop access is not guarenteed as adult\n"); return false; } @@ -619,7 +622,7 @@ bool EntranceShuffler::ReplaceEntrance(Entrance* entrance, Entrance* target, std std::string ticks = std::to_string(svcGetSystemTick()); auto message = "Dumping World Graph at " + ticks + "\n"; // SPDLOG_DEBUG(message); - // Areas::DumpWorldGraph(ticks); + // Regions::DumpWorldGraph(ticks); #endif rollbacks.push_back(EntrancePair{ entrance, target }); mCurNumRandomizedEntrances++; @@ -629,7 +632,7 @@ bool EntranceShuffler::ReplaceEntrance(Entrance* entrance, Entrance* target, std std::string ticks = std::to_string(svcGetSystemTick()); auto message = "Dumping World Graph at " + ticks + "\n"; // SPDLOG_DEBUG(message); - // Areas::DumpWorldGraph(ticks); + // Regions::DumpWorldGraph(ticks); #endif if (entrance->GetConnectedRegionKey() != RR_NONE) { RestoreConnections(entrance, target); @@ -765,7 +768,7 @@ static std::array, 2> SplitEntrancesByRequirements(std::v Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); } // run a search to see what's accessible - GetAccessibleLocations({}); + ReachabilitySearch({}); for (Entrance* entrance : entrancesToSplit) { // if an entrance is accessible at all times of day by both ages, it's a soft entrance with no restrictions @@ -881,7 +884,7 @@ void EntranceShuffler::ShuffleEntrancePool(std::vector& entrancePool, auto message = "Failed to connect entrances. Retrying " + std::to_string(retries) + " more times.\nDumping World Graph at " + ticks + "\n"; SPDLOG_DEBUG(message); - // Areas::DumpWorldGraph(ticks); + // Regions::DumpWorldGraph(ticks); #endif } retries--; diff --git a/soh/soh/Enhancements/randomizer/entrance.h b/soh/soh/Enhancements/randomizer/entrance.h index 08861ff0d8b..38c2bb22b95 100644 --- a/soh/soh/Enhancements/randomizer/entrance.h +++ b/soh/soh/Enhancements/randomizer/entrance.h @@ -50,10 +50,10 @@ class Entrance { bool CheckConditionAtAgeTime(bool& age, bool& time, bool passAnyway = false) const; RandomizerRegion GetConnectedRegionKey() const; RandomizerRegion GetOriginalConnectedRegionKey() const; - Area* GetConnectedRegion() const; + Region* GetConnectedRegion() const; void SetParentRegion(RandomizerRegion newParent); RandomizerRegion GetParentRegionKey() const; - Area* GetParentRegion() const; + Region* GetParentRegion() const; void SetNewEntrance(RandomizerRegion newRegion); void SetAsShuffled(); bool IsShuffled() const; diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index 52789f17ed1..79355322057 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -1,13 +1,24 @@ #include "3drando/pool_functions.hpp" #include "../../OTRGlobals.h" #include "fishsanity.h" +#include "draw.h" #include "variables.h" #include "functions.h" #include "macros.h" #include +extern "C" { +#include "src/overlays/actors/ovl_Fishing/z_fishing.h" +#include "src/overlays/actors/ovl_En_Fish/z_en_fish.h" + +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + #define FSi OTRGlobals::Instance->gRandoContext->GetFishsanity() +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() + /** * @brief Parallel list of pond fish checks for both ages */ @@ -40,9 +51,14 @@ std::unordered_map Rando::StaticData::randomizerGrottoF { 0x29, RC_ZR_OPEN_GROTTO_FISH } }; +ActorFunc drawFishing = NULL; +ActorFunc drawEnFish = NULL; +Color_RGBA16 fsPulseColor = { 30, 240, 200 }; + namespace Rando { const FishIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK }; bool Fishsanity::fishsanityHelpersInit = false; + s16 Fishsanity::fishGroupCounter = 0; std::unordered_map Fishsanity::pondFishAgeMap; std::vector Fishsanity::childPondFish; std::vector Fishsanity::adultPondFish; @@ -75,7 +91,7 @@ namespace Rando { } // Are overworld fish enabled, and is this an overworld fish location? if (mode != RO_FISHSANITY_POND && (loc->GetScene() == SCENE_GROTTOS || loc->GetScene() == SCENE_ZORAS_DOMAIN) - && loc->GetActorID() == ACTOR_EN_FISH && (loc->GetActorParams() == 1 || loc->GetActorParams() < 0)) { + && loc->GetActorID() == ACTOR_EN_FISH && (loc->GetActorParams() >> 8)) { return true; } // Must not be an included fish location! @@ -87,10 +103,10 @@ namespace Rando { auto [mode, numFish, ageSplit] = GetOptions(optionsSource); std::vector activeFish; std::vector remainingFish; + std::vector pondFish = Rando::StaticData::GetPondFishLocations(); // Fishsanity_InitializeHelpers(); - remainingFish.insert(remainingFish.end(), Rando::StaticData::pondFishLocations.begin(), - Rando::StaticData::pondFishLocations.end()); + remainingFish.insert(remainingFish.end(), pondFish.begin(), pondFish.end()); // No pond fish shuffled if (numFish == 0) { @@ -138,8 +154,8 @@ namespace Rando { // Add overworld fish if (mode == RO_FISHSANITY_OVERWORLD || mode == RO_FISHSANITY_BOTH) { - activeFish.insert(activeFish.end(), Rando::StaticData::overworldFishLocations.begin(), - Rando::StaticData::overworldFishLocations.end()); + std::vector overworldFish = Rando::StaticData::GetOverworldFishLocations(); + activeFish.insert(activeFish.end(), overworldFish.begin(), overworldFish.end()); } return std::make_pair(activeFish, remainingFish); @@ -299,11 +315,11 @@ namespace Rando { FishsanityCheckType Fishsanity::GetCheckType(RandomizerCheck rc) { // Is this a pond fish? - if (std::binary_search(Rando::StaticData::pondFishLocations.begin(), Rando::StaticData::pondFishLocations.end(), rc)) + if (std::binary_search(Rando::StaticData::GetPondFishLocations().begin(), Rando::StaticData::GetPondFishLocations().end(), rc)) return FSC_POND; // Is this an overworld fish? - if (std::binary_search(Rando::StaticData::overworldFishLocations.begin(), Rando::StaticData::overworldFishLocations.end(), rc)) { + if (std::binary_search(Rando::StaticData::GetOverworldFishLocations().begin(), Rando::StaticData::GetOverworldFishLocations().end(), rc)) { if (rc < RC_ZD_FISH_1) return FSC_GROTTO; else @@ -321,12 +337,136 @@ namespace Rando { return GetCheckType(fish->randomizerCheck) != FSC_NONE; } - void Fishsanity::SetPendingFish(FishIdentity* fish) { - mPendingFish = fish == NULL ? defaultIdentity : *fish; + void Fishsanity::OnActorInitHandler(void* refActor) { + Actor* actor = static_cast(refActor); + + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + FishIdentity fish; + + if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + // Set fish ID for ZD fish + if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && actor->params == -1) { + actor->params ^= fishGroupCounter++; + } else if (gPlayState->sceneNum == SCENE_GROTTOS && actor->params == 1) { + actor->params = 0x100 | gSaveContext.respawn[RESPAWN_MODE_RETURN].data; + } + + fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + // Render fish as randomized item + if (Rando::Fishsanity::IsFish(&fish) && !Flags_GetRandomizerInf(fish.randomizerInf)) { + if (!drawEnFish) { + drawEnFish = actor->draw; + } + actor->draw = Fishsanity_DrawEnFish; + } + return; + } + + if (actor->id == ACTOR_FISHING && gPlayState->sceneNum == SCENE_FISHING_POND && actor->params >= 100 && + actor->params <= 117 && fs->GetPondFishShuffled()) { + // Initialize pond fish for fishsanity + // Initialize fishsanity metadata on this actor + Fishing* fishActor = static_cast(refActor); + //fishActor->fishsanityParams = actor->params; + fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + + // With every pond fish shuffled, caught fish will not spawn unless all fish have been caught. + if (RAND_GET_OPTION(RSK_FISHSANITY_POND_COUNT) > 16 && + !fs->GetPondCleared()) { + // Create effect for uncaught fish + if (!Flags_GetRandomizerInf(fish.randomizerInf)) { + actor->shape.shadowDraw = Fishsanity_DrawEffShadow; + if (!drawFishing) { + drawFishing = actor->draw; + } + actor->draw = Fishsanity_DrawFishing; + } + } + } } - FishIdentity Fishsanity::GetPendingFish() { - return mPendingFish; + void Fishsanity::OnFlagSetHandler(int16_t flagType, int16_t flag) { + if (flagType != FLAG_RANDOMIZER_INF) { + return; + } + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)flag); + FishsanityCheckType fsType = Rando::Fishsanity::GetCheckType(rc); + if (fsType == FSC_NONE) { + return; + } + + // When a pond fish is caught, advance the pond. + if (fsType == FSC_POND) { + OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); + } + } + + void Fishsanity::OnActorUpdateHandler(void* refActor) { + if (gPlayState->sceneNum != SCENE_GROTTOS && gPlayState->sceneNum != SCENE_ZORAS_DOMAIN && gPlayState->sceneNum != SCENE_FISHING_POND) { + return; + } + + Actor* actor = static_cast(refActor); + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + + // Detect fish catch + if (actor->id == ACTOR_FISHING && fs->GetPondFishShuffled()) { + Fishing* fish = static_cast(refActor); + + // State 6 -> Fish caught and hoisted + if (fish->fishState == 6) { + FishIdentity identity = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + if (identity.randomizerCheck != RC_UNKNOWN_CHECK) { + Flags_SetRandomizerInf(identity.randomizerInf); + // Remove uncaught effect + if (actor->shape.shadowDraw != NULL) { + actor->shape.shadowDraw = NULL; + actor->draw = drawFishing; + } + } + } + } + + if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + EnFish* fishActor = static_cast(refActor); + if (Rando::Fishsanity::IsFish(&fish) && Flags_GetRandomizerInf(fish.randomizerInf)) { + // Reset draw method + if (actor->draw == Fishsanity_DrawEnFish) { + actor->draw = drawEnFish; + } + } + + if (((actor->params >> 8) > 0) && fishActor->respawnTimer > 0) { + Actor_Kill(actor); + } + } + + // Reset fish group counter when the group gets culled + if (actor->id == ACTOR_OBJ_MURE && gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && fishGroupCounter > 0 && + !(actor->flags & ACTOR_FLAG_UPDATE_WHILE_CULLED) && fs->GetOverworldFishShuffled()) { + fishGroupCounter = 0; + } + } + + void Fishsanity::OnSceneInitHandler(int16_t sceneNum) { + if (sceneNum == SCENE_ZORAS_DOMAIN) { + fishGroupCounter = 0; + } + } + + void Fishsanity::OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* refActor) { + Actor* actor = static_cast(refActor); + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + + if (id == VB_BOTTLE_ACTOR && actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) { + Flags_SetRandomizerInf(fish.randomizerInf); + actor->parent = &GET_PLAYER(gPlayState)->actor; + *should = false; + } + } } } // namespace Rando @@ -344,10 +484,6 @@ extern "C" { return FSi->IsAdultPond(); } - void Randomizer_SetPendingFish(FishIdentity* fish) { - return FSi->SetPendingFish(fish); - } - void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) { Vec3f pos, ripplePos; static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; @@ -394,6 +530,28 @@ extern "C" { } } + void Fishsanity_DrawEnFish(struct Actor* actor, struct PlayState* play) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(play->sceneNum, actor->params); + GetItemEntry randoItem = Rando::Context::GetInstance()->GetFinalGIEntry(fish.randomizerCheck, true, GI_FISH); + if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { + randoItem = GET_ITEM_MYSTERY; + } + + Matrix_Push(); + Matrix_Scale(30.0, 30.0, 30.0, MTXMODE_APPLY); + + EnItem00_CustomItemsParticles(actor, play, randoItem); + GetItemEntry_Draw(play, randoItem); + + Matrix_Pop(); + } + + void Fishsanity_DrawFishing(struct Actor* actor, struct PlayState* play) { + Fishsanity_OpenGreyscaleColor(play, &fsPulseColor, (actor->params - 100) * 20); + drawFishing(actor, play); + Fishsanity_CloseGreyscaleColor(play); + } + void Fishsanity_OpenGreyscaleColor(PlayState* play, Color_RGBA16* color, int16_t frameOffset) { OPEN_DISPS(play->state.gfxCtx); gDPSetGrayscaleColor( diff --git a/soh/soh/Enhancements/randomizer/fishsanity.h b/soh/soh/Enhancements/randomizer/fishsanity.h index fb12811625b..8d6108725dd 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.h +++ b/soh/soh/Enhancements/randomizer/fishsanity.h @@ -4,6 +4,7 @@ #include #include "randomizerTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" typedef struct FishsanityPondOptions { u8 mode; @@ -128,15 +129,34 @@ class Fishsanity { FishIdentity AdvancePond(); /** - * @brief Set the currently held fish - * @param fish Pointer to FishIdentity to copy + * @brief ActorInit hook handler for fishsanity */ - void SetPendingFish(FishIdentity* fish); + static void OnActorInitHandler(void* refActor); /** - * @brief Get the currently held fish + * @brief FlagSet hook handler for fishsanity */ - FishIdentity GetPendingFish(); + static void OnFlagSetHandler(int16_t flagType, int16_t flag); + + /** + * @brief PlayerUpdate hook handler for fishsanity + */ + static void OnPlayerUpdateHandler(); + + /** + * @brief ActorUpdate hook handler for fishsanity + */ + static void OnActorUpdateHandler(void* refActor); + + /** + * @brief SceneInit hook handler for fishsanity + */ + static void OnSceneInitHandler(int16_t sceneNum); + + /** + * @brief VB hook handler for fishsanity + */ + static void OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* refActor); private: /** @@ -152,22 +172,19 @@ class Fishsanity { * @return The FishIdentity for the described fish */ static FishIdentity GetPondFish(s16 params, bool adultPond); - + /** * @brief Current pond fish when all pond fish are not randomized */ std::pair mCurrPondFish; - /** - * @brief Identity of the last-caught fish in the fishing pond minigame awaiting reward - */ - FishIdentity mPendingFish; - /** * @brief True if fishsanity helpers have been initialized */ static bool fishsanityHelpersInit; + static s16 fishGroupCounter; + ///////////////////////////////////////////////////////// //// Helper data structures derived from static data //// ///////////////////////////////////////////////////////// @@ -197,10 +214,12 @@ bool Randomizer_GetPondFishShuffled(); bool Randomizer_GetOverworldFishShuffled(); /// Returns true if the adult fishing pond should be used for fishsanity. bool Randomizer_IsAdultPond(); -/// Sets the pending fish -void Randomizer_SetPendingFish(FishIdentity* fish); /// Custom shadow draw function to add effect to uncollected fish void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play); +/// Overriden actor draw function for bottleable fish +void Fishsanity_DrawEnFish(struct Actor* actor, struct PlayState* play); +/// Overriden actor draw function for the fishing pond +void Fishsanity_DrawFishing(struct Actor* actor, struct PlayState* play); void Fishsanity_OpenGreyscaleColor(PlayState* play, Color_RGBA16* color, int16_t frameOffset); void Fishsanity_CloseGreyscaleColor(PlayState* play); #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 4bd8da74259..75e9dd290cf 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -4,6 +4,7 @@ #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/dungeon.h" +#include "soh/Enhancements/randomizer/fishsanity.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -12,6 +13,7 @@ extern "C" { #include "functions.h" #include "variables.h" #include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h" #include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" #include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h" @@ -305,7 +307,9 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { auto loc = Rando::Context::GetInstance()->GetItemLocation(randomizerQueuedCheck); if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, static_cast(randomizerQueuedCheck)); - loc->MarkAsObtained(); + loc->SetCheckStatus(RCSHOW_COLLECTED); + CheckTracker::RecalculateAllAreaTotals(); + SaveManager::Instance->SaveSection(gSaveContext.fileNum, SECTION_ID_TRACKER_DATA, true); randomizerQueuedCheck = RC_UNKNOWN_CHECK; randomizerQueuedItemEntry = GET_ITEM_NONE; } @@ -614,6 +618,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void case VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT: *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); break; + case VB_MIDO_SPAWN: + if (RAND_GET_OPTION(RSK_FOREST) != RO_FOREST_OPEN && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) { + *should = true; + } + break; case VB_MOVE_MIDO_IN_KOKIRI_FOREST: if (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN) { *should = true; @@ -629,7 +638,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); break; case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS: - *should = !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && MeetsLACSRequirements(); + *should = + LINK_IS_ADULT && + (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + MeetsLACSRequirements(); break; case VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW: *should = @@ -656,7 +669,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; } else { *should = true; - Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->MarkAsObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->SetCheckStatus(RCSHOW_COLLECTED); + CheckTracker::RecalculateAllAreaTotals(); } break; case VB_ITEM00_DESPAWN: { @@ -676,6 +690,17 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } break; } + case VB_ITEM_B_HEART_DESPAWN: { + ItemBHeart* itemBHeart = static_cast(optionalArg); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemBHeart->actor.id, gPlayState->sceneNum, itemBHeart->actor.params); + if (rc != RC_UNKNOWN_CHECK) { + itemBHeart->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + itemBHeart->actor.draw = (ActorFunc)ItemBHeart_DrawRandomizedItem; + itemBHeart->actor.update = (ActorFunc)ItemBHeart_UpdateRandomizedItem; + *should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained(); + } + break; + } case VB_MALON_ALREADY_TAUGHT_EPONAS_SONG: { *should = Flags_GetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); break; @@ -766,6 +791,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void Randomizer_Item_Give(gPlayState, item00->itemEntry); } } + // This is typically called when you close the text box after getting an item, in case a previous + // function hid the interface. + Interface_ChangeAlpha(gSaveContext.unk_13EE); // EnItem00_SetupAction(item00, func_8001E5C8); // *should = false; } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { @@ -1173,25 +1201,26 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { // probably need to do something different when we implement shuffle if (sceneNum == SCENE_TREASURE_BOX_SHOP) { Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->SetCheckStatus(RCSHOW_UNCHECKED); + CheckTracker::RecalculateAllAreaTotals(); } // LACs & Prelude checks @@ -1202,6 +1231,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { updateHook = 0; } + // If we're not in the Temple of Time or we've already learned the Prelude of Light and received LACs, we don't need to do anything if ( sceneNum != SCENE_TEMPLE_OF_TIME || ( @@ -1215,15 +1245,18 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); } - if (!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && MeetsLACSRequirements()) { + // We're always in rando here, and rando always overrides this should so we can just pass false + if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, false, NULL)) { Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); } + // If both awards have been given, we can unregister the hook, otherwise it will get unregistered when the player leaves the area if ( Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) ) { GameInteractor::Instance->UnregisterGameHook(updateHook); + updateHook = 0; } }); } @@ -1330,16 +1363,6 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } - if (actor->id == ACTOR_ITEM_B_HEART) { - ItemBHeart* itemBHeart = static_cast(actorRef); - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemBHeart->actor.id, gPlayState->sceneNum, itemBHeart->actor.params); - if (rc != RC_UNKNOWN_CHECK) { - itemBHeart->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); - itemBHeart->actor.draw = (ActorFunc)ItemBHeart_DrawRandomizedItem; - itemBHeart->actor.update = (ActorFunc)ItemBHeart_UpdateRandomizedItem; - } - } - if (actor->id == ACTOR_EN_DNS) { EnDns* enDns = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); @@ -1465,6 +1488,14 @@ void RandomizerOnActorInitHandler(void* actorRef) { } } + if (actor->id == ACTOR_BG_TREEMOUTH && LINK_IS_ADULT && + RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && + (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN || + Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD))) { + BgTreemouth* bgTreemouth = static_cast(actorRef); + bgTreemouth->unk_168 = 1.0f; + } + //consumable bags if ( actor->id == ACTOR_EN_ITEM00 && @@ -1495,6 +1526,12 @@ void RandomizerRegisterHooks() { static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; + static uint32_t fishsanityOnActorInitHook = 0; + static uint32_t fishsanityOnFlagSetHook = 0; + static uint32_t fishsanityOnActorUpdateHook = 0; + static uint32_t fishsanityOnSceneInitHook = 0; + static uint32_t fishsanityOnVanillaBehaviorHook = 0; + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { randomizerQueuedChecks = std::queue(); randomizerQueuedCheck = RC_UNKNOWN_CHECK; @@ -1509,6 +1546,12 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnFlagSetHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnSceneInitHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnVanillaBehaviorHook); + onFlagSetHook = 0; onSceneFlagSetHook = 0; onPlayerUpdateForRCQueueHook = 0; @@ -1518,6 +1561,12 @@ void RandomizerRegisterHooks() { onSceneInitHook = 0; onActorInitHook = 0; + fishsanityOnActorInitHook = 0; + fishsanityOnFlagSetHook = 0; + fishsanityOnActorUpdateHook = 0; + fishsanityOnSceneInitHook = 0; + fishsanityOnVanillaBehaviorHook = 0; + if (!IS_RANDO) return; onFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnFlagSetHandler); @@ -1528,5 +1577,15 @@ void RandomizerRegisterHooks() { onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); + + if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { + OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); + + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorInitHandler); + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnFlagSetHandler); + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorUpdateHandler); + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnSceneInitHandler); + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnVanillaBehaviorHandler); + } }); } diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 5fbab59a83c..2d3f4845111 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -39,16 +39,14 @@ Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, void Item::ApplyEffect() const { auto ctx = Rando::Context::GetInstance(); - ctx->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true); + ctx->GetLogic()->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true); ctx->GetLogic()->SetInLogic(logicVal, true); - ctx->GetLogic()->UpdateHelpers(); } void Item::UndoEffect() const { auto ctx = Rando::Context::GetInstance(); - ctx->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false); + ctx->GetLogic()->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false); ctx->GetLogic()->SetInLogic(logicVal, false); - ctx->GetLogic()->UpdateHelpers(); } const Text& Item::GetName() const { @@ -83,16 +81,22 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio if (giEntry != nullptr) { return giEntry; } - auto ctx = Rando::Context::GetInstance(); + std::shared_ptr ctx = Rando::Context::GetInstance(); + auto logic = ctx->GetLogic(); RandomizerGet actual = RG_NONE; - const bool tycoonWallet = - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS; - const u8 infiniteUpgrades = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES); + const bool tycoonWallet = !( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) + ) + ); + const u8 infiniteUpgrades = ctx->GetOption(RSK_INFINITE_UPGRADES).Value(); switch (randomizerGet) { case RG_PROGRESSIVE_STICK_UPGRADE: - switch (ctx->CurrentUpgrade(UPG_STICKS)) { + switch (logic->CurrentUpgrade(UPG_STICKS)) { case 0: - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { + if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { actual = RG_DEKU_STICK_BAG; break; } @@ -119,9 +123,9 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_NUT_UPGRADE: - switch (ctx->CurrentUpgrade(UPG_NUTS)) { + switch (logic->CurrentUpgrade(UPG_NUTS)) { case 0: - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { + if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) { actual = RG_DEKU_NUT_BAG; break; } @@ -148,7 +152,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_BOMB_BAG: - switch (ctx->CurrentUpgrade(UPG_BOMB_BAG)) { + switch (logic->CurrentUpgrade(UPG_BOMB_BAG)) { case 0: actual = RG_BOMB_BAG; break; @@ -175,7 +179,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_BOW: - switch (ctx->CurrentUpgrade(UPG_QUIVER)) { + switch (logic->CurrentUpgrade(UPG_QUIVER)) { case 0: actual = RG_FAIRY_BOW; break; @@ -202,7 +206,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_SLINGSHOT: - switch (ctx->CurrentUpgrade(UPG_BULLET_BAG)) { + switch (logic->CurrentUpgrade(UPG_BULLET_BAG)) { case 0: actual = RG_FAIRY_SLINGSHOT; break; @@ -229,7 +233,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_OCARINA: - switch (ctx->CurrentInventory(ITEM_OCARINA_FAIRY)) { + switch (logic->CurrentInventory(ITEM_OCARINA_FAIRY)) { case ITEM_NONE: actual = RG_FAIRY_OCARINA; break; @@ -242,7 +246,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_HOOKSHOT: - switch (ctx->CurrentInventory(ITEM_HOOKSHOT)) { + switch (logic->CurrentInventory(ITEM_HOOKSHOT)) { case ITEM_NONE: actual = RG_HOOKSHOT; break; @@ -255,7 +259,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_STRENGTH: - switch (ctx->CurrentUpgrade(UPG_STRENGTH)) { + switch (logic->CurrentUpgrade(UPG_STRENGTH)) { case 0: actual = RG_GORONS_BRACELET; break; @@ -271,11 +275,11 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_WALLET: - if (!ctx->CheckRandoInf(RAND_INF_HAS_WALLET)) { + if (!logic->CheckRandoInf(RAND_INF_HAS_WALLET)) { actual = RG_CHILD_WALLET; break; } - switch (ctx->CurrentUpgrade(UPG_WALLET)) { + switch (logic->CurrentUpgrade(UPG_WALLET)) { case 0: actual = RG_ADULT_WALLET; break; @@ -298,11 +302,11 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_SCALE: - if (!ctx->CheckRandoInf(RAND_INF_CAN_SWIM)) { + if (!logic->CheckRandoInf(RAND_INF_CAN_SWIM)) { actual = RG_BRONZE_SCALE; break; } - switch (ctx->CurrentUpgrade(UPG_SCALE)) { + switch (logic->CurrentUpgrade(UPG_SCALE)) { case 0: actual = RG_SILVER_SCALE; break; @@ -315,7 +319,7 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_MAGIC_METER: - switch (ctx->GetSaveContext()->magicLevel) { + switch (logic->GetSaveContext()->magicLevel) { case 0: actual = RG_MAGIC_SINGLE; break; @@ -338,11 +342,11 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio actual = RG_BIGGORON_SWORD; break; case RG_PROGRESSIVE_BOMBCHUS: - if (ctx->CurrentInventory(ITEM_BOMBCHU) == ITEM_NONE) { + if (logic->CurrentInventory(ITEM_BOMBCHU) == ITEM_NONE) { actual = RG_BOMBCHU_20; } else if (infiniteUpgrades != RO_INF_UPGRADES_OFF) { actual = RG_BOMBCHU_INF; - } else if (ctx->GetAmmo(ITEM_BOMBCHU) < 5) { + } else if (logic->GetAmmo(ITEM_BOMBCHU) < 5) { actual = RG_BOMBCHU_10; } else { actual = RG_BOMBCHU_5; diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index 3185fce8aa1..0cce409fca7 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -74,8 +74,6 @@ void ItemLocation::PlaceVanillaItem() { void ItemLocation::ApplyPlacedItemEffect() const { StaticData::RetrieveItem(placedItem).ApplyEffect(); - auto ctx = Context::GetInstance(); - ctx->GetLogic()->UpdateHelpers(); } uint16_t ItemLocation::GetPrice() const { @@ -102,15 +100,23 @@ void ItemLocation::SetCustomPrice(const uint16_t price_) { } bool ItemLocation::HasObtained() const { - return obtained; + return status == RCSHOW_COLLECTED || status == RCSHOW_SAVED; } -void ItemLocation::MarkAsObtained() { - obtained = true; +void ItemLocation::SetCheckStatus(RandomizerCheckStatus status_) { + status = status_; } -void ItemLocation::MarkAsNotObtained() { - obtained = false; +RandomizerCheckStatus ItemLocation::GetCheckStatus() { + return status; +} + +void ItemLocation::SetIsSkipped(bool isSkipped_) { + isSkipped = isSkipped_; +} + +bool ItemLocation::GetIsSkipped() { + return isSkipped; } bool ItemLocation::IsHintable() const { @@ -166,13 +172,13 @@ void ItemLocation::AddExcludeOption() { // RANDOTODO: this without string compares and loops bool alreadyAdded = false; const Location* loc = StaticData::GetLocation(rc); - for (const Option* location : Context::GetInstance()->GetSettings()->GetExcludeOptionsForGroup(loc->GetCollectionCheckGroup())) { + for (const Option* location : Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea())) { if (location->GetName() == excludedOption.GetName()) { alreadyAdded = true; } } if (!alreadyAdded) { - Context::GetInstance()->GetSettings()->GetExcludeOptionsForGroup(loc->GetCollectionCheckGroup()).push_back(&excludedOption); + Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea()).push_back(&excludedOption); } } @@ -213,6 +219,7 @@ void ItemLocation::ResetVariables() { wothCandidate = false; barrenCandidate = false; area = RA_NONE; - obtained = false; + status = RCSHOW_UNCHECKED; + isSkipped = false; } } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index b40cac537b8..868b384b5dc 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -32,8 +32,10 @@ class ItemLocation { bool HasCustomPrice() const; void SetCustomPrice(uint16_t price_); bool HasObtained() const; - void MarkAsObtained(); - void MarkAsNotObtained(); + void SetCheckStatus(RandomizerCheckStatus status_); + RandomizerCheckStatus GetCheckStatus(); + void SetIsSkipped(bool isSkipped_); + bool GetIsSkipped(); bool IsHintable() const; void SetAsHintable(); bool IsAHintAccessible() const; @@ -70,6 +72,7 @@ class ItemLocation { bool visibleInImGui = false; bool wothCandidate = false; bool barrenCandidate = false; - bool obtained = false; + RandomizerCheckStatus status = RCSHOW_UNCHECKED; + bool isSkipped = false; }; } // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index ddc9f7fc208..135fddeea3e 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -1,6 +1,7 @@ #include "location.h" #include "static_data.h" #include +#include RandomizerCheck Rando::Location::GetRandomizerCheck() const { return rc; @@ -10,10 +11,6 @@ Rando::SpoilerCollectionCheck Rando::Location::GetCollectionCheck() const { return collectionCheck; } -SpoilerCollectionCheckGroup Rando::Location::GetCollectionCheckGroup() const { - return collectionCheckGroup; -} - RandomizerCheckQuest Rando::Location::GetQuest() const { return quest; } @@ -35,11 +32,7 @@ int32_t Rando::Location::GetActorParams() const { } SceneID Rando::Location::GetScene() const { - return static_cast(scene); -} - -uint8_t Rando::Location::GetFlag() const { - return flag; + return scene; } RandomizerHintTextKey Rando::Location::GetHintKey() const { @@ -58,19 +51,11 @@ const std::string& Rando::Location::GetShortName() const { return shortName; } -Rando::LocationType Rando::Location::GetLocationType() const { - return locationType; -} - -bool Rando::Location::IsCategory(Category category) const { - return std::any_of(categories.begin(), categories.end(), [category](auto entry) { return entry == category; }); -} - bool Rando::Location::IsDungeon() const { - return (locationType != LocationType::GSToken && + return (checkType != RCTYPE_SKULL_TOKEN && (scene < SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || (scene > SCENE_TREASURE_BOX_SHOP && scene < SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR))) || - (locationType == LocationType::GSToken && scene < SCENE_GANONS_TOWER); + (checkType == RCTYPE_SKULL_TOKEN && scene < SCENE_GANONS_TOWER); } bool Rando::Location::IsOverworld() const { @@ -97,312 +82,289 @@ RandomizerGet Rando::Location::GetVanillaItem() const { return vanillaItem; } -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, std::string&& spoilerName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Base, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Base, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Chest, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Chest, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Chest, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Chest, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable( - RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable( - RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, const uint8_t collectFlag_, - SpoilerCollectionCheckGroup collectionCheckGroup, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, collectFlag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, const uint8_t collectFlag_, - SpoilerCollectionCheckGroup collectionCheckGroup, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, collectFlag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Collectable, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_SKULL_TOKEN, area_, LocationType::GSToken, ACTOR_EN_SI, scene_, actorParams_, - flag_, std::move(shortName_), std::move(spoilerName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, - std::move(categories), isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_SKULL_TOKEN, area_, LocationType::GSToken, ACTOR_EN_SI, scene_, actorParams_, - flag_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, - std::move(categories), isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, scene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - std::vector&& categories, const uint8_t skullScene_, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_SKULL_TOKEN, area_, LocationType::GSToken, ACTOR_EN_SI, scene_, actorParams_, - flag_, std::move(shortName_), std::move(spoilerName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, - std::move(categories), isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - std::vector&& categories, const uint8_t skullScene_, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_SKULL_TOKEN, area_, LocationType::GSToken, ACTOR_EN_SI, scene_, actorParams_, - flag_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, - std::move(categories), isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_), - collectionCheckGroup}; -} - -Rando::Location Rando::Location::GrottoScrub(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, +RandomizerCheckArea GetAreaFromScene(uint8_t scene) { + switch (scene) { + case SCENE_LINKS_HOUSE: + case SCENE_KOKIRI_FOREST: + case SCENE_KOKIRI_SHOP: + case SCENE_MIDOS_HOUSE: + case SCENE_KNOW_IT_ALL_BROS_HOUSE: + case SCENE_TWINS_HOUSE: + case SCENE_SARIAS_HOUSE: + return RCAREA_KOKIRI_FOREST; + + case SCENE_LOST_WOODS: + return RCAREA_LOST_WOODS; + + case SCENE_SACRED_FOREST_MEADOW: + return RCAREA_SACRED_FOREST_MEADOW; + + case SCENE_HYRULE_FIELD: + return RCAREA_HYRULE_FIELD; + + case SCENE_LAKE_HYLIA: + case SCENE_FISHING_POND: + case SCENE_LAKESIDE_LABORATORY: + return RCAREA_LAKE_HYLIA; + + case SCENE_GERUDO_VALLEY: + case SCENE_CARPENTERS_TENT: + return RCAREA_GERUDO_VALLEY; + + case SCENE_GERUDOS_FORTRESS: + case SCENE_THIEVES_HIDEOUT: + return RCAREA_GERUDO_FORTRESS; + + case SCENE_HAUNTED_WASTELAND: + return RCAREA_WASTELAND; + + case SCENE_DESERT_COLOSSUS: + return RCAREA_DESERT_COLOSSUS; + + case SCENE_MARKET_ENTRANCE_DAY: + case SCENE_MARKET_ENTRANCE_NIGHT: + case SCENE_MARKET_ENTRANCE_RUINS: + case SCENE_BACK_ALLEY_DAY: + case SCENE_BACK_ALLEY_NIGHT: + case SCENE_BACK_ALLEY_HOUSE: + case SCENE_MARKET_DAY: + case SCENE_MARKET_NIGHT: + case SCENE_MARKET_RUINS: + case SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY: + case SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT: + case SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS: + case SCENE_TREASURE_BOX_SHOP: + case SCENE_BOMBCHU_BOWLING_ALLEY: + case SCENE_DOG_LADY_HOUSE: + case SCENE_MARKET_GUARD_HOUSE: + case SCENE_POTION_SHOP_MARKET: + case SCENE_BOMBCHU_SHOP: + case SCENE_HAPPY_MASK_SHOP: + case SCENE_TEMPLE_OF_TIME: + return RCAREA_MARKET; + + case SCENE_HYRULE_CASTLE: + case SCENE_CASTLE_COURTYARD_GUARDS_DAY: + case SCENE_CASTLE_COURTYARD_GUARDS_NIGHT: + case SCENE_CASTLE_COURTYARD_ZELDA: + case SCENE_OUTSIDE_GANONS_CASTLE: + return RCAREA_HYRULE_CASTLE; + + case SCENE_KAKARIKO_VILLAGE: + case SCENE_KAKARIKO_CENTER_GUEST_HOUSE: + case SCENE_HOUSE_OF_SKULLTULA: + case SCENE_POTION_SHOP_GRANNY: + case SCENE_IMPAS_HOUSE: + case SCENE_POTION_SHOP_KAKARIKO: + case SCENE_TEST01: + return RCAREA_KAKARIKO_VILLAGE; + + case SCENE_GRAVEYARD: + case SCENE_ROYAL_FAMILYS_TOMB: + case SCENE_GRAVEKEEPERS_HUT: + return RCAREA_GRAVEYARD; + + case SCENE_DEATH_MOUNTAIN_TRAIL: + return RCAREA_DEATH_MOUNTAIN_TRAIL; + + case SCENE_GORON_CITY: + case SCENE_GORON_SHOP: + return RCAREA_GORON_CITY; + + case SCENE_DEATH_MOUNTAIN_CRATER: + return RCAREA_DEATH_MOUNTAIN_CRATER; + + case SCENE_ZORAS_RIVER: + return RCAREA_ZORAS_RIVER; + + case SCENE_ZORAS_DOMAIN: + case SCENE_ZORA_SHOP: + return RCAREA_ZORAS_DOMAIN; + + case SCENE_ZORAS_FOUNTAIN: + return RCAREA_ZORAS_FOUNTAIN; + + case SCENE_LON_LON_RANCH: + case SCENE_LON_LON_BUILDINGS: + case SCENE_STABLE: + return RCAREA_LON_LON_RANCH; + + case SCENE_DEKU_TREE: + case SCENE_DEKU_TREE_BOSS: + return RCAREA_DEKU_TREE; + + case SCENE_DODONGOS_CAVERN: + case SCENE_DODONGOS_CAVERN_BOSS: + return RCAREA_DODONGOS_CAVERN; + + case SCENE_JABU_JABU: + case SCENE_JABU_JABU_BOSS: + return RCAREA_JABU_JABUS_BELLY; + + case SCENE_FOREST_TEMPLE: + case SCENE_FOREST_TEMPLE_BOSS: + return RCAREA_FOREST_TEMPLE; + + case SCENE_FIRE_TEMPLE: + case SCENE_FIRE_TEMPLE_BOSS: + return RCAREA_FIRE_TEMPLE; + + case SCENE_WATER_TEMPLE: + case SCENE_WATER_TEMPLE_BOSS: + return RCAREA_WATER_TEMPLE; + + case SCENE_SPIRIT_TEMPLE: + case SCENE_SPIRIT_TEMPLE_BOSS: + return RCAREA_SPIRIT_TEMPLE; + + case SCENE_SHADOW_TEMPLE: + case SCENE_SHADOW_TEMPLE_BOSS: + return RCAREA_SHADOW_TEMPLE; + + case SCENE_BOTTOM_OF_THE_WELL: + return RCAREA_BOTTOM_OF_THE_WELL; + + case SCENE_ICE_CAVERN: + return RCAREA_ICE_CAVERN; + + case SCENE_GERUDO_TRAINING_GROUND: + return RCAREA_GERUDO_TRAINING_GROUND; + + case SCENE_INSIDE_GANONS_CASTLE: + case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: + case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR: + case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: + case SCENE_GANONS_TOWER: + case SCENE_GANON_BOSS: + return RCAREA_GANONS_CASTLE; + default: + assert(false); + return RCAREA_INVALID; + } +} + +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, + isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, + SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, + SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, + SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) }; +} + +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::GrottoScrub, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::GrottoScrub(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, - const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, + SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) }; +} + +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::GrottoScrub, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Delayed(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Delayed, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Delayed(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::Delayed, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Reward(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::TempleReward, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::Reward(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - const RandomizerHintTextKey hintKey, - const RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck, - SpoilerCollectionCheckGroup collectionCheckGroup, bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::TempleReward, actorId_, scene_, actorParams_, flag_, - std::move(shortName_), hintKey, vanillaItem, std::move(categories), - isVanillaCompletion_, collectionCheck, collectionCheckGroup}; -} - -Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, - uint8_t scene_, - std::string&& shortName_, std::string&& spoilerName_, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::OtherHint, actorId_, scene_, 0x00, 0x00, - std::move(shortName_), std::move(spoilerName_), RHT_NONE, RG_NONE, {}, isVanillaCompletion_}; -} - -Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, - uint8_t scene_, - std::string&& shortName_, - bool isVanillaCompletion_) { - return {rc, quest_, checkType_, area_, LocationType::OtherHint, actorId_, scene_, 0x00, 0x00, - std::move(shortName_), RHT_NONE, RG_NONE, {}, isVanillaCompletion_}; -} - -Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, - std::vector&& categories, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_GOSSIP_STONE, area_, LocationType::Base, ACTOR_EN_GS, scene_, actorParams_, flag_, - std::move(shortName_), std::move(spoilerName_), RHT_NONE, RG_NONE, std::move(categories), - isVanillaCompletion_}; -} - -Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, - std::vector&& categories, bool isVanillaCompletion_) { - return {rc, quest_, RCTYPE_GOSSIP_STONE, area_, LocationType::Base, ACTOR_EN_GS, scene_, actorParams_, flag_, - std::move(shortName_), RHT_NONE, RG_NONE, std::move(categories), - isVanillaCompletion_}; -} \ No newline at end of file + return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + const RandomizerHintTextKey hintKey) { + return { rc, quest_, RCTYPE_SKULL_TOKEN, GetAreaFromScene(scene_), ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, scene_, flag_) }; +} + +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const uint8_t skullScene_) { + return { rc, quest_, RCTYPE_SKULL_TOKEN, GetAreaFromScene(scene_), ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; +} + +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, const uint8_t skullScene_) { + return { rc, quest_, RCTYPE_SKULL_TOKEN, area_, ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; +} + +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, + std::string&& spoilerName_) { + return { rc, quest_, RCTYPE_STATIC_HINT, area_, actorId_, scene_, 0x00, std::move(shortName_), std::move(spoilerName_), RHT_NONE, RG_NONE, false }; +} + +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, std::string&& shortName_) { + return { rc, quest_, RCTYPE_STATIC_HINT, GetAreaFromScene(scene_), actorId_, scene_, 0x00, std::move(shortName_), RHT_NONE, RG_NONE, false }; +} + +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_) { + return { rc, quest_, RCTYPE_STATIC_HINT, area_, actorId_, scene_, 0x00, std::move(shortName_), RHT_NONE, RG_NONE, false }; +} + +Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { + return { rc, quest_, RCTYPE_GOSSIP_STONE, GetAreaFromScene(scene_), ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; +} + +Rando::Location Rando::Location::Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, int32_t actorParams_, RandomizerInf flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem) { + return {rc, quest_, RCTYPE_FISH, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, + SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, scene_, flag_)}; +} + +Rando::Location Rando::Location::GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, int32_t actorParams_, RandomizerInf flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey) { + return {rc, quest_, RCTYPE_FISH, area_, ACTOR_EN_FISH, SCENE_GROTTOS, actorParams_, std::move(shortName_), hintKey, RG_FISH, false, + SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, SCENE_GROTTOS, flag_)}; +} + +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, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; +} diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index bd7f69a8bbc..09a015a1e2c 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -4,7 +4,6 @@ #include #include "3drando/spoiler_log.hpp" -#include "3drando/category.hpp" #include "3drando/hints.hpp" #include "randomizerTypes.h" @@ -20,17 +19,7 @@ class SpoilerCollectionCheck { uint16_t flag = 0; SpoilerCollectionCheck() = default; - SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_) - : type(type_), scene(scene_), flag(flag_) { - } - - static auto None() { - return SpoilerCollectionCheck(SPOILER_CHK_NONE, 0x00, 0x00); - } - - static auto AlwaysCollected() { - return SpoilerCollectionCheck(SPOILER_CHK_ALWAYS_COLLECTED, 0x00, 0x00); - } + SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_) : type(type_), scene(scene_), flag(flag_) {} static auto ItemGetInf(const uint8_t slot) { return SpoilerCollectionCheck(SPOILER_CHK_ITEM_GET_INF, 0x00, slot); @@ -52,76 +41,30 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene, flag); } - static auto Fish(const uint8_t flag, const uint8_t scene = SCENE_FISHING_POND) { - return SpoilerCollectionCheck(SPOILER_CHK_FISH, scene, flag); - } - - static auto Fishing(const uint8_t bit) { - return SpoilerCollectionCheck(SPOILER_CHK_MINIGAME, 0x00, bit); - } - - static auto BigPoePoints() { - return SpoilerCollectionCheck(SPOILER_CHK_POE_POINTS, 0x00, 0x00); - } - - static auto Gravedigger(const uint8_t scene, const uint8_t flag) { - return SpoilerCollectionCheck(SPOILER_CHK_GRAVEDIGGER, scene, flag); - } - - static auto ShopItem(const uint8_t scene, const uint8_t itemSlot) { - return SpoilerCollectionCheck(SPOILER_CHK_SHOP_ITEM, scene, itemSlot); - } - - static auto MasterSword() { - return SpoilerCollectionCheck(SPOILER_CHK_MASTER_SWORD, 0x00, 0x00); - } - static auto RandomizerInf(const uint16_t flag) { return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, 0x00, flag); } }; -enum class LocationType { - Base, - Chest, - Collectable, - GSToken, - GrottoScrub, - Delayed, - TempleReward, - HintStone, - OtherHint, -}; - class Location { public: - Location() : rc(RC_UNKNOWN_CHECK), quest(RCQUEST_BOTH), checkType(RCTYPE_STANDARD), area(RCAREA_INVALID), - locationType(LocationType::Base), actorId(ACTOR_ID_MAX), scene(SCENE_ID_MAX), actorParams(0), - flag(0), hintKey(RHT_NONE), vanillaItem(RG_NONE), isVanillaCompletion(false), - collectionCheck(SpoilerCollectionCheck()), collectionCheckGroup(GROUP_NO_GROUP) {} - Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, - const RandomizerCheckArea area_, const LocationType locationType_, const ActorID actorId_, const uint8_t scene_, - const int32_t actorParams_, const uint8_t flag_, std::string shortName_, std::string spoilerName_, - const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, std::vector categories_, - const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), - const SpoilerCollectionCheckGroup collectionCheckGroup_ = GROUP_NO_GROUP) - : rc(rc_), quest(quest_), checkType(checkType_), area(area_), locationType(locationType_), actorId(actorId_), - scene(scene_), actorParams(actorParams_), flag(flag_), shortName(std::move(shortName_)), - spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), categories(std::move(categories_)), - isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), - collectionCheckGroup(collectionCheckGroup_) { - } - Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, - const RandomizerCheckArea area_, const LocationType locationType_, const ActorID actorId_, const uint8_t scene_, - const int32_t actorParams_, const uint8_t flag_, std::string shortName_, - const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, std::vector categories_, - const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), - const SpoilerCollectionCheckGroup collectionCheckGroup_ = GROUP_NO_GROUP) - : rc(rc_), quest(quest_), checkType(checkType_), area(area_), locationType(locationType_), actorId(actorId_), - scene(scene_), actorParams(actorParams_), flag(flag_), shortName(shortName_), - spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), categories(std::move(categories_)), - isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), - collectionCheckGroup(collectionCheckGroup_) {} + Location() : rc(RC_UNKNOWN_CHECK), quest(RCQUEST_BOTH), checkType(RCTYPE_STANDARD), area(RCAREA_INVALID), actorId(ACTOR_ID_MAX), scene(SCENE_ID_MAX), actorParams(0), + hintKey(RHT_NONE), vanillaItem(RG_NONE), isVanillaCompletion(false), collectionCheck(SpoilerCollectionCheck()) {} + + Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, + const SceneID scene_, const int32_t actorParams_, std::string shortName_, std::string spoilerName_, const RandomizerHintTextKey hintKey_, + const RandomizerGet vanillaItem_, const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck()) + : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), + scene(scene_), actorParams(actorParams_), shortName(std::move(shortName_)), + spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), + isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_) {} + + Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, + const SceneID scene_, const int32_t actorParams_, std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, + const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck()) + : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), actorParams(actorParams_), shortName(shortName_), + spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), + collectionCheck(collectionCheck_) {} static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { if (area < 0 || area >= RCAREA_INVALID) { @@ -132,20 +75,16 @@ class Location { RandomizerCheck GetRandomizerCheck() const; SpoilerCollectionCheck GetCollectionCheck() const; - SpoilerCollectionCheckGroup GetCollectionCheckGroup() const; RandomizerCheckQuest GetQuest() const; RandomizerCheckArea GetArea() const; RandomizerCheckType GetRCType() const; ActorID GetActorID() const; int32_t GetActorParams() const; SceneID GetScene() const; - uint8_t GetFlag() const; RandomizerHintTextKey GetHintKey() const; HintText* GetHint(); const std::string& GetName() const; const std::string& GetShortName() const; - LocationType GetLocationType() const; - bool IsCategory(Category category) const; bool IsDungeon() const; bool IsOverworld() const; bool IsShop() const; @@ -154,119 +93,53 @@ class Location { const HintText& GetHint() const; RandomizerGet GetVanillaItem() const; - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, std::string&& spoilerName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); - static Location - Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, uint8_t collectFlag_, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, uint8_t collectFlag_, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = true); - - static Location - GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, std::vector&& categories, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = true); + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); + + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_ = false); + + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + bool isVanillaCompletion_ = false); + + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + bool isVanillaCompletion_ = false); + + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); + + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey); /// @brief For certain scenes, the sceneId and the "Scene" in spoiler collection check later used to check the /// GS flags don't necessarily match. Use this constructor (or the next one) for those. scene_ should be the actual scene where @@ -274,117 +147,51 @@ class Location { /// and expected that these don't always match, and the naming is a holdover from 3drando. /// @param rc /// @param quest_ - /// @param area_ /// @param scene_ /// @param actorParams_ /// @param flag_ /// @param shortName_ - /// @param spoilerName_ /// @param hintKey - /// @param categories - /// @param collectionCheckGroup /// @param skullScene_ - /// @param isVanillaCompletion_ /// @return - static Location - GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, std::vector&& categories, - uint8_t skullScene_, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = true); - - static Location - GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, std::vector&& categories, - uint8_t skullScene_, - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = true); - - static Location - GrottoScrub(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - GrottoScrub(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, std::vector&& categories, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Delayed(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Delayed(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, - bool isVanillaCompletion_ = false); - - static Location - Reward(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, bool isVanillaCompletion_ = false); - - static Location - Reward(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, - ActorID actorId_, uint8_t scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - SpoilerCollectionCheckGroup collectionCheckGroup = GROUP_NO_GROUP, bool isVanillaCompletion_ = false); - - static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - std::string&& shortName_, std::string&& spoilerName_, bool isVanillaCompletion_ = false); - - static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - RandomizerCheckArea area_, ActorID actorId_, uint8_t scene_, - std::string&& shortName_, bool isVanillaCompletion_ = false); - - static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, std::string&& spoilerName_, - std::vector&& categories, bool isVanillaCompletion_ = false); - - static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, uint8_t scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - std::vector&& categories, bool isVanillaCompletion_ = false); + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey, uint8_t skullScene_); + + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, uint8_t skullScene_); + + static Location Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + RandomizerInf flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem); + + static Location GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, int32_t actorParams_, + RandomizerInf flag_, std::string&& shortName_, RandomizerHintTextKey hintKey); + + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, + std::string&& spoilerName_); + + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, std::string&& shortName_); + + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_); + + static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); + + static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); private: RandomizerCheck rc; RandomizerCheckQuest quest; RandomizerCheckType checkType; RandomizerCheckArea area; - LocationType locationType; ActorID actorId; - uint8_t scene; + SceneID scene; int32_t actorParams; - uint8_t flag; bool checked = false; std::string shortName; std::string spoilerName; RandomizerHintTextKey hintKey; RandomizerGet vanillaItem; - std::vector categories; bool isVanillaCompletion; SpoilerCollectionCheck collectionCheck; - SpoilerCollectionCheckGroup collectionCheckGroup; bool isHintable = false; }; } // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index dd31dae5c9d..9b2b3b0a71d 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -6,1377 +6,878 @@ std::array Rando::StaticData::locationTable; std::multimap, RandomizerCheck> Rando::StaticData::CheckFromActorMultimap; -std::vector KF_ShopLocations = { - RC_KF_SHOP_ITEM_1, RC_KF_SHOP_ITEM_2, RC_KF_SHOP_ITEM_3, RC_KF_SHOP_ITEM_4, - RC_KF_SHOP_ITEM_5, RC_KF_SHOP_ITEM_6, RC_KF_SHOP_ITEM_7, RC_KF_SHOP_ITEM_8, -}; -std::vector Kak_PotionShopLocations = { - RC_KAK_POTION_SHOP_ITEM_1, RC_KAK_POTION_SHOP_ITEM_2, RC_KAK_POTION_SHOP_ITEM_3, RC_KAK_POTION_SHOP_ITEM_4, - RC_KAK_POTION_SHOP_ITEM_5, RC_KAK_POTION_SHOP_ITEM_6, RC_KAK_POTION_SHOP_ITEM_7, RC_KAK_POTION_SHOP_ITEM_8, -}; -std::vector MK_BombchuShopLocations = { - RC_MARKET_BOMBCHU_SHOP_ITEM_1, RC_MARKET_BOMBCHU_SHOP_ITEM_2, RC_MARKET_BOMBCHU_SHOP_ITEM_3, - RC_MARKET_BOMBCHU_SHOP_ITEM_4, RC_MARKET_BOMBCHU_SHOP_ITEM_5, RC_MARKET_BOMBCHU_SHOP_ITEM_6, - RC_MARKET_BOMBCHU_SHOP_ITEM_7, RC_MARKET_BOMBCHU_SHOP_ITEM_8, -}; -std::vector MK_PotionShopLocations = { - RC_MARKET_POTION_SHOP_ITEM_1, RC_MARKET_POTION_SHOP_ITEM_2, RC_MARKET_POTION_SHOP_ITEM_3, - RC_MARKET_POTION_SHOP_ITEM_4, RC_MARKET_POTION_SHOP_ITEM_5, RC_MARKET_POTION_SHOP_ITEM_6, - RC_MARKET_POTION_SHOP_ITEM_7, RC_MARKET_POTION_SHOP_ITEM_8, -}; -std::vector MK_BazaarLocations = { - RC_MARKET_BAZAAR_ITEM_1, RC_MARKET_BAZAAR_ITEM_2, RC_MARKET_BAZAAR_ITEM_3, RC_MARKET_BAZAAR_ITEM_4, - RC_MARKET_BAZAAR_ITEM_5, RC_MARKET_BAZAAR_ITEM_6, RC_MARKET_BAZAAR_ITEM_7, RC_MARKET_BAZAAR_ITEM_8, -}; -std::vector Kak_BazaarLocations = { - RC_KAK_BAZAAR_ITEM_1, RC_KAK_BAZAAR_ITEM_2, RC_KAK_BAZAAR_ITEM_3, RC_KAK_BAZAAR_ITEM_4, - RC_KAK_BAZAAR_ITEM_5, RC_KAK_BAZAAR_ITEM_6, RC_KAK_BAZAAR_ITEM_7, RC_KAK_BAZAAR_ITEM_8, -}; -std::vector ZD_ShopLocations = { - RC_ZD_SHOP_ITEM_1, RC_ZD_SHOP_ITEM_2, RC_ZD_SHOP_ITEM_3, RC_ZD_SHOP_ITEM_4, - RC_ZD_SHOP_ITEM_5, RC_ZD_SHOP_ITEM_6, RC_ZD_SHOP_ITEM_7, RC_ZD_SHOP_ITEM_8, -}; -std::vector GC_ShopLocations = { - RC_GC_SHOP_ITEM_1, RC_GC_SHOP_ITEM_2, RC_GC_SHOP_ITEM_3, RC_GC_SHOP_ITEM_4, - RC_GC_SHOP_ITEM_5, RC_GC_SHOP_ITEM_6, RC_GC_SHOP_ITEM_7, RC_GC_SHOP_ITEM_8, -}; -// List of shop location lists, used for shop shuffle -std::vector> Rando::StaticData::shopLocationLists = { - KF_ShopLocations, Kak_PotionShopLocations, MK_BombchuShopLocations, MK_PotionShopLocations, - MK_BazaarLocations, Kak_BazaarLocations, ZD_ShopLocations, GC_ShopLocations, -}; - -std::vector Rando::StaticData::scrubLocations = { - RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, - RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, - RC_LW_DEKU_SCRUB_NEAR_BRIDGE, - RC_LW_DEKU_SCRUB_GROTTO_REAR, - RC_LW_DEKU_SCRUB_GROTTO_FRONT, - RC_SFM_DEKU_SCRUB_GROTTO_REAR, - RC_SFM_DEKU_SCRUB_GROTTO_FRONT, - RC_HF_DEKU_SCRUB_GROTTO, - RC_LH_DEKU_SCRUB_GROTTO_LEFT, - RC_LH_DEKU_SCRUB_GROTTO_RIGHT, - RC_LH_DEKU_SCRUB_GROTTO_CENTER, - RC_GV_DEKU_SCRUB_GROTTO_REAR, - RC_GV_DEKU_SCRUB_GROTTO_FRONT, - RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, - RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, - RC_GC_DEKU_SCRUB_GROTTO_LEFT, - RC_GC_DEKU_SCRUB_GROTTO_RIGHT, - RC_GC_DEKU_SCRUB_GROTTO_CENTER, - RC_DMC_DEKU_SCRUB, - RC_DMC_DEKU_SCRUB_GROTTO_LEFT, - RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, - RC_DMC_DEKU_SCRUB_GROTTO_CENTER, - RC_ZR_DEKU_SCRUB_GROTTO_REAR, - RC_ZR_DEKU_SCRUB_GROTTO_FRONT, - RC_LLR_DEKU_SCRUB_GROTTO_LEFT, - RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, - RC_LLR_DEKU_SCRUB_GROTTO_CENTER, - RC_DEKU_TREE_MQ_DEKU_SCRUB, - RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, - RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, - RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, - RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, - RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, - RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, - RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, - RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - RC_JABU_JABUS_BELLY_DEKU_SCRUB, - RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, - RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, - RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, - RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, - RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, - RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, - RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, - RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, - RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, -}; - std::vector Rando::StaticData::dungeonRewardLocations = { // Bosses RC_QUEEN_GOHMA, RC_KING_DODONGO, RC_BARINADE, RC_PHANTOM_GANON, RC_VOLVAGIA, RC_MORPHA, RC_TWINROVA, RC_BONGO_BONGO, RC_LINKS_POCKET, }; -std::vector Rando::StaticData::overworldLocations = { - // Kokiri Forest - RC_KF_KOKIRI_SWORD_CHEST, - RC_KF_MIDOS_TOP_LEFT_CHEST, - RC_KF_MIDOS_TOP_RIGHT_CHEST, - RC_KF_MIDOS_BOTTOM_LEFT_CHEST, - RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, - RC_KF_STORMS_GROTTO_CHEST, - RC_KF_LINKS_HOUSE_COW, - - // Shop - RC_KF_SHOP_ITEM_1, - RC_KF_SHOP_ITEM_2, - RC_KF_SHOP_ITEM_3, - RC_KF_SHOP_ITEM_4, - RC_KF_SHOP_ITEM_5, - RC_KF_SHOP_ITEM_6, - RC_KF_SHOP_ITEM_7, - RC_KF_SHOP_ITEM_8, - - // Lost Woods - RC_LW_GIFT_FROM_SARIA, - RC_LW_SKULL_KID, - RC_LW_TRADE_COJIRO, - RC_LW_TRADE_ODD_POTION, - RC_LW_OCARINA_MEMORY_GAME, - RC_LW_TARGET_IN_WOODS, - RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, - RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, - RC_LW_DEKU_SCRUB_NEAR_BRIDGE, - RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, - RC_LW_DEKU_SCRUB_GROTTO_REAR, - RC_LW_DEKU_SCRUB_GROTTO_FRONT, - RC_DEKU_THEATER_SKULL_MASK, - RC_DEKU_THEATER_MASK_OF_TRUTH, - - // Sacred Forest Meadow - RC_SONG_FROM_SARIA, - RC_SHEIK_IN_FOREST, - RC_SFM_WOLFOS_GROTTO_CHEST, - RC_SFM_DEKU_SCRUB_GROTTO_REAR, - RC_SFM_DEKU_SCRUB_GROTTO_FRONT, - - // Hyrule Field - RC_HF_SOUTHEAST_GROTTO_CHEST, - RC_HF_OPEN_GROTTO_CHEST, - RC_HF_NEAR_MARKET_GROTTO_CHEST, - RC_HF_OCARINA_OF_TIME_ITEM, - RC_SONG_FROM_OCARINA_OF_TIME, - RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, - RC_HF_DEKU_SCRUB_GROTTO, - RC_HF_COW_GROTTO_COW, - - // Lake Hylia - RC_LH_CHILD_FISHING, - RC_LH_ADULT_FISHING, - RC_LH_HYRULE_LOACH, - RC_LH_LAB_DIVE, - RC_LH_TRADE_FROG, - RC_LH_UNDERWATER_ITEM, - RC_LH_SUN, - RC_LH_FREESTANDING_POH, - RC_LH_DEKU_SCRUB_GROTTO_LEFT, - RC_LH_DEKU_SCRUB_GROTTO_RIGHT, - RC_LH_DEKU_SCRUB_GROTTO_CENTER, - - // Gerudo Valley - RC_GV_CHEST, - RC_GV_TRADE_SAW, - RC_GV_WATERFALL_FREESTANDING_POH, - RC_GV_CRATE_FREESTANDING_POH, - RC_GV_DEKU_SCRUB_GROTTO_REAR, - RC_GV_DEKU_SCRUB_GROTTO_FRONT, - RC_GV_COW, - - // Gerudo Fortress - RC_GF_CHEST, - RC_GF_HBA_1000_POINTS, - RC_GF_HBA_1500_POINTS, - RC_GF_NORTH_F1_CARPENTER, - RC_GF_NORTH_F2_CARPENTER, - RC_GF_SOUTH_F1_CARPENTER, - RC_GF_SOUTH_F2_CARPENTER, - RC_GF_GERUDO_MEMBERSHIP_CARD, - - // Haunted Wasteland - RC_WASTELAND_CHEST, - RC_WASTELAND_BOMBCHU_SALESMAN, - - // Desert Colossus - RC_SHEIK_AT_COLOSSUS, - RC_COLOSSUS_FREESTANDING_POH, - RC_COLOSSUS_GREAT_FAIRY_REWARD, - RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, - RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, - - // Market - RC_MARKET_TREASURE_CHEST_GAME_REWARD, - RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, - RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, - RC_MARKET_LOST_DOG, - RC_MARKET_SHOOTING_GALLERY_REWARD, - RC_MARKET_10_BIG_POES, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, - RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, - RC_MARKET_TREASURE_CHEST_GAME_KEY_1, - RC_MARKET_TREASURE_CHEST_GAME_KEY_2, - RC_MARKET_TREASURE_CHEST_GAME_KEY_3, - RC_MARKET_TREASURE_CHEST_GAME_KEY_4, - RC_MARKET_TREASURE_CHEST_GAME_KEY_5, - - // Market Shops - RC_MARKET_BOMBCHU_SHOP_ITEM_1, - RC_MARKET_BOMBCHU_SHOP_ITEM_2, - RC_MARKET_BOMBCHU_SHOP_ITEM_3, - RC_MARKET_BOMBCHU_SHOP_ITEM_4, - RC_MARKET_BOMBCHU_SHOP_ITEM_5, - RC_MARKET_BOMBCHU_SHOP_ITEM_6, - RC_MARKET_BOMBCHU_SHOP_ITEM_7, - RC_MARKET_BOMBCHU_SHOP_ITEM_8, - RC_MARKET_POTION_SHOP_ITEM_1, - RC_MARKET_POTION_SHOP_ITEM_2, - RC_MARKET_POTION_SHOP_ITEM_3, - RC_MARKET_POTION_SHOP_ITEM_4, - RC_MARKET_POTION_SHOP_ITEM_5, - RC_MARKET_POTION_SHOP_ITEM_6, - RC_MARKET_POTION_SHOP_ITEM_7, - RC_MARKET_POTION_SHOP_ITEM_8, - RC_MARKET_BAZAAR_ITEM_1, - RC_MARKET_BAZAAR_ITEM_2, - RC_MARKET_BAZAAR_ITEM_3, - RC_MARKET_BAZAAR_ITEM_4, - RC_MARKET_BAZAAR_ITEM_5, - RC_MARKET_BAZAAR_ITEM_6, - RC_MARKET_BAZAAR_ITEM_7, - RC_MARKET_BAZAAR_ITEM_8, - - // Hyrule Castle - RC_HC_MALON_EGG, - RC_HC_ZELDAS_LETTER, - RC_SONG_FROM_IMPA, - RC_HC_GREAT_FAIRY_REWARD, - RC_OGC_GREAT_FAIRY_REWARD, - - // Temple of Time - RC_TOT_MASTER_SWORD, - RC_SHEIK_AT_TEMPLE, - RC_TOT_LIGHT_ARROWS_CUTSCENE, - RC_GIFT_FROM_SAGES, - - // Kakariko - RC_SHEIK_IN_KAKARIKO, - RC_KAK_REDEAD_GROTTO_CHEST, - RC_KAK_OPEN_GROTTO_CHEST, - RC_KAK_10_GOLD_SKULLTULA_REWARD, - RC_KAK_20_GOLD_SKULLTULA_REWARD, - RC_KAK_30_GOLD_SKULLTULA_REWARD, - RC_KAK_40_GOLD_SKULLTULA_REWARD, - RC_KAK_50_GOLD_SKULLTULA_REWARD, - RC_KAK_100_GOLD_SKULLTULA_REWARD, - RC_KAK_MAN_ON_ROOF, - RC_KAK_SHOOTING_GALLERY_REWARD, - RC_KAK_TRADE_ODD_MUSHROOM, - RC_KAK_GRANNYS_SHOP, - RC_KAK_ANJU_AS_CHILD, - RC_KAK_ANJU_AS_ADULT, - RC_KAK_TRADE_POCKET_CUCCO, - RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, - RC_KAK_WINDMILL_FREESTANDING_POH, - RC_SONG_FROM_WINDMILL, - RC_KAK_IMPAS_HOUSE_COW, - - // Kakariko Shops - RC_KAK_POTION_SHOP_ITEM_1, - RC_KAK_POTION_SHOP_ITEM_2, - RC_KAK_POTION_SHOP_ITEM_3, - RC_KAK_POTION_SHOP_ITEM_4, - RC_KAK_POTION_SHOP_ITEM_5, - RC_KAK_POTION_SHOP_ITEM_6, - RC_KAK_POTION_SHOP_ITEM_7, - RC_KAK_POTION_SHOP_ITEM_8, - RC_KAK_BAZAAR_ITEM_1, - RC_KAK_BAZAAR_ITEM_2, - RC_KAK_BAZAAR_ITEM_3, - RC_KAK_BAZAAR_ITEM_4, - RC_KAK_BAZAAR_ITEM_5, - RC_KAK_BAZAAR_ITEM_6, - RC_KAK_BAZAAR_ITEM_7, - RC_KAK_BAZAAR_ITEM_8, - - // Graveyard - RC_GRAVEYARD_HOOKSHOT_CHEST, - RC_GRAVEYARD_SHIELD_GRAVE_CHEST, - RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, - RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, - RC_SONG_FROM_ROYAL_FAMILYS_TOMB, - RC_GRAVEYARD_FREESTANDING_POH, - RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, - RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, - - // Death Mountain Trail - RC_DMT_CHEST, - RC_DMT_STORMS_GROTTO_CHEST, - RC_DMT_TRADE_BROKEN_SWORD, - RC_DMT_TRADE_EYEDROPS, - RC_DMT_TRADE_CLAIM_CHECK, - RC_DMT_GREAT_FAIRY_REWARD, - RC_DMT_FREESTANDING_POH, - RC_DMT_COW_GROTTO_COW, - - // Goron City - RC_GC_MAZE_LEFT_CHEST, - RC_GC_MAZE_CENTER_CHEST, - RC_GC_MAZE_RIGHT_CHEST, - RC_GC_ROLLING_GORON_AS_CHILD, - RC_GC_ROLLING_GORON_AS_ADULT, - RC_GC_DARUNIAS_JOY, - RC_GC_POT_FREESTANDING_POH, - RC_GC_DEKU_SCRUB_GROTTO_LEFT, - RC_GC_DEKU_SCRUB_GROTTO_RIGHT, - RC_GC_DEKU_SCRUB_GROTTO_CENTER, - RC_GC_MEDIGORON, - - // Goron City Shop - RC_GC_SHOP_ITEM_1, - RC_GC_SHOP_ITEM_2, - RC_GC_SHOP_ITEM_3, - RC_GC_SHOP_ITEM_4, - RC_GC_SHOP_ITEM_5, - RC_GC_SHOP_ITEM_6, - RC_GC_SHOP_ITEM_7, - RC_GC_SHOP_ITEM_8, - - // Death Mountain - RC_DMC_UPPER_GROTTO_CHEST, - RC_DMC_WALL_FREESTANDING_POH, - RC_DMC_VOLCANO_FREESTANDING_POH, - RC_SHEIK_IN_CRATER, - RC_DMC_DEKU_SCRUB, - RC_DMC_GREAT_FAIRY_REWARD, - RC_DMC_DEKU_SCRUB_GROTTO_LEFT, - RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, - RC_DMC_DEKU_SCRUB_GROTTO_CENTER, - - // Zoras River - RC_ZR_OPEN_GROTTO_CHEST, - RC_ZR_MAGIC_BEAN_SALESMAN, - RC_ZR_FROGS_ZELDAS_LULLABY, - RC_ZR_FROGS_EPONAS_SONG, - RC_ZR_FROGS_SARIAS_SONG, - RC_ZR_FROGS_SUNS_SONG, - RC_ZR_FROGS_SONG_OF_TIME, - RC_ZR_FROGS_IN_THE_RAIN, - RC_ZR_FROGS_OCARINA_GAME, - RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, - RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, - RC_ZR_DEKU_SCRUB_GROTTO_REAR, - RC_ZR_DEKU_SCRUB_GROTTO_FRONT, - - // Zoras Domain - RC_ZD_CHEST, - RC_ZD_DIVING_MINIGAME, - RC_ZD_KING_ZORA_THAWED, - RC_ZD_TRADE_PRESCRIPTION, - - // Zora's Domain Shop - RC_ZD_SHOP_ITEM_1, - RC_ZD_SHOP_ITEM_2, - RC_ZD_SHOP_ITEM_3, - RC_ZD_SHOP_ITEM_4, - RC_ZD_SHOP_ITEM_5, - RC_ZD_SHOP_ITEM_6, - RC_ZD_SHOP_ITEM_7, - RC_ZD_SHOP_ITEM_8, - - // Zoras Fountain - RC_ZF_ICEBERC_FREESTANDING_POH, - RC_ZF_BOTTOM_FREESTANDING_POH, - RC_ZF_GREAT_FAIRY_REWARD, - - // Lon Lon Ranch - RC_SONG_FROM_MALON, - RC_LLR_TALONS_CHICKENS, - RC_LLR_FREESTANDING_POH, - RC_LLR_DEKU_SCRUB_GROTTO_LEFT, - RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, - RC_LLR_DEKU_SCRUB_GROTTO_CENTER, - RC_LLR_STABLES_LEFT_COW, - RC_LLR_STABLES_RIGHT_COW, - RC_LLR_TOWER_LEFT_COW, - RC_LLR_TOWER_RIGHT_COW, - - /*------------------------------- - --- GOLD SKULLTULA TOKENS --- - -------------------------------*/ - - // Overworld - RC_KF_GS_BEAN_PATCH, - RC_KF_GS_KNOW_IT_ALL_HOUSE, - RC_KF_GS_HOUSE_OF_TWINS, - - RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, - RC_LW_GS_BEAN_PATCH_NEAR_THEATER, - RC_LW_GS_ABOVE_THEATER, - RC_SFM_GS, - - RC_HF_GS_COW_GROTTO, - RC_HF_GS_NEAR_KAK_GROTTO, - - RC_LH_GS_BEAN_PATCH, - RC_LH_GS_SMALL_ISLAND, - RC_LH_GS_LAB_WALL, - RC_LH_GS_LAB_CRATE, - RC_LH_GS_TREE, - - RC_GV_GS_BEAN_PATCH, - RC_GV_GS_SMALL_BRIDGE, - RC_GV_GS_PILLAR, - RC_GV_GS_BEHIND_TENT, - - RC_GF_GS_ARCHERY_RANGE, - RC_GF_GS_TOP_FLOOR, - - RC_WASTELAND_GS, - RC_COLOSSUS_GS_BEAN_PATCH, - RC_COLOSSUS_GS_HILL, - RC_COLOSSUS_GS_TREE, - - RC_OGC_GS, - RC_HC_GS_STORMS_GROTTO, - RC_HC_GS_TREE, - RC_MARKET_GS_GUARD_HOUSE, - - RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, - RC_KAK_GS_SKULLTULA_HOUSE, - RC_KAK_GS_GUARDS_HOUSE, - RC_KAK_GS_TREE, - RC_KAK_GS_WATCHTOWER, - RC_KAK_GS_ABOVE_IMPAS_HOUSE, - - RC_DMC_GS_BEAN_PATCH, - RC_DMC_GS_CRATE, - - RC_DMT_GS_BEAN_PATCH, - RC_DMT_GS_NEAR_KAK, - RC_DMT_GS_ABOVE_DODONGOS_CAVERN, - RC_DMT_GS_FALLING_ROCKS_PATH, - - RC_GC_GS_CENTER_PLATFORM, - RC_GC_GS_BOULDER_MAZE, - RC_GRAVEYARD_GS_WALL, - RC_GRAVEYARD_GS_BEAN_PATCH, - - RC_ZR_GS_LADDER, - RC_ZR_GS_TREE, - RC_ZR_GS_ABOVE_BRIDGE, - RC_ZR_GS_NEAR_RAISED_GROTTOS, - - RC_ZD_GS_FROZEN_WATERFALL, - RC_ZF_GS_ABOVE_THE_LOG, - RC_ZF_GS_HIDDEN_CAVE, - RC_ZF_GS_TREE, +using namespace Rando; - RC_LLR_GS_BACK_WALL, - RC_LLR_GS_RAIN_SHED, - RC_LLR_GS_HOUSE_WINDOW, - RC_LLR_GS_TREE, +std::vector Rando::StaticData::GetPondFishLocations() { + std::vector pondFishLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_FISH && location.GetScene() == SCENE_FISHING_POND && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + pondFishLocations.push_back(location.GetRandomizerCheck()); + } + } + return pondFishLocations; +} - RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, - RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, - RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, - RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, - RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, - RC_SFM_STORMS_GROTTO_BEEHIVE, - RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, - RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, - RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, - RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, - RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, - RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, - RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, - RC_LLR_GROTTO_BEEHIVE, - RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, - RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, - RC_DMT_COW_GROTTO_BEEHIVE, - RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, - RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, - RC_GC_GROTTO_BEEHIVE, - RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, - RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, - RC_DMC_HAMMER_GROTTO_BEEHIVE, - RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, - RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, - RC_ZR_STORMS_GROTTO_BEEHIVE, - RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, - RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, - RC_ZD_BEHIND_KING_ZORA_BEEHIVE, - RC_LH_GROTTO_BEEHIVE, - RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, - RC_COLOSSUS_GROTTO_BEEHIVE, -}; +std::vector Rando::StaticData::GetOverworldFishLocations() { + std::vector overworldFishLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_FISH && location.GetScene() != SCENE_FISHING_POND && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + overworldFishLocations.push_back(location.GetRandomizerCheck()); + } + } + return overworldFishLocations; +} -std::vector Rando::StaticData::gossipStoneLocations = { - RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, - RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, - RC_KF_GOSSIP_STONE, - RC_KF_STORMS_GROTTO_GOSSIP_STONE, - RC_LW_GOSSIP_STONE, - RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, - RC_SFM_MAZE_LOWER_GOSSIP_STONE, - RC_SFM_MAZE_UPPER_GOSSIP_STONE, - RC_SFM_SARIA_GOSSIP_STONE, - RC_HF_COW_GROTTO_GOSSIP_STONE, - RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, - RC_HF_OPEN_GROTTO_GOSSIP_STONE, - RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, - RC_TOT_LEFT_CENTER_GOSSIP_STONE, - RC_TOT_LEFTMOST_GOSSIP_STONE, - RC_TOT_RIGHT_CENTER_GOSSIP_STONE, - RC_TOT_RIGHTMOST_GOSSIP_STONE, - RC_HC_MALON_GOSSIP_STONE, - RC_HC_ROCK_WALL_GOSSIP_STONE, - RC_HC_STORMS_GROTTO_GOSSIP_STONE, - RC_KAK_OPEN_GROTTO_GOSSIP_STONE, - RC_GRAVEYARD_GOSSIP_STONE, - RC_DMT_GOSSIP_STONE, - RC_DMT_STORMS_GROTTO_GOSSIP_STONE, - RC_GC_MAZE_GOSSIP_STONE, - RC_GC_MEDIGORON_GOSSIP_STONE, - RC_DMC_GOSSIP_STONE, - RC_DMC_UPPER_GROTTO_GOSSIP_STONE, - RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, - RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, - RC_ZR_OPEN_GROTTO_GOSSIP_STONE, - RC_ZD_GOSSIP_STONE, - RC_ZF_JABU_GOSSIP_STONE, - RC_ZF_FAIRY_GOSSIP_STONE, - RC_LH_LAB_GOSSIP_STONE, - RC_LH_SOUTHEAST_GOSSIP_STONE, - RC_LH_SOUTHWEST_GOSSIP_STONE, - RC_GV_GOSSIP_STONE, - RC_COLOSSUS_GOSSIP_STONE, - RC_DODONGOS_CAVERN_GOSSIP_STONE, -}; +std::vector Rando::StaticData::GetStaticHintLocations() { + std::vector staticHintLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_STATIC_HINT && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + staticHintLocations.push_back(location.GetRandomizerCheck()); + } + } + return staticHintLocations; +} -std::vector Rando::StaticData::staticHintLocations = { - RC_GANONDORF_HINT, - RC_SHEIK_HINT_GC, - RC_SHEIK_HINT_MQ_GC, - RC_DAMPE_HINT, - RC_GREG_HINT, - RC_SARIA_SONG_HINT, - RC_ALTAR_HINT_CHILD, - RC_ALTAR_HINT_ADULT, - RC_FISHING_POLE_HINT, - RC_TOT_SHEIK_HINT, - RC_MASK_SHOP_HINT, -}; +std::vector Rando::StaticData::GetScrubLocations() { + std::vector scrubLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_SCRUB && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + scrubLocations.push_back(location.GetRandomizerCheck()); + } + } + return scrubLocations; +} -std::vector Rando::StaticData::pondFishLocations = { - RC_LH_CHILD_FISH_1, RC_LH_CHILD_FISH_2, RC_LH_CHILD_FISH_3, RC_LH_CHILD_FISH_4, RC_LH_CHILD_FISH_5, - RC_LH_CHILD_FISH_6, RC_LH_CHILD_FISH_7, RC_LH_CHILD_FISH_8, RC_LH_CHILD_FISH_9, RC_LH_CHILD_FISH_10, - RC_LH_CHILD_FISH_11, RC_LH_CHILD_FISH_12, RC_LH_CHILD_FISH_13, RC_LH_CHILD_FISH_14, RC_LH_CHILD_FISH_15, - RC_LH_CHILD_LOACH_1, RC_LH_CHILD_LOACH_2, RC_LH_ADULT_FISH_1, RC_LH_ADULT_FISH_2, RC_LH_ADULT_FISH_3, - RC_LH_ADULT_FISH_4, RC_LH_ADULT_FISH_5, RC_LH_ADULT_FISH_6, RC_LH_ADULT_FISH_7, RC_LH_ADULT_FISH_8, - RC_LH_ADULT_FISH_9, RC_LH_ADULT_FISH_10, RC_LH_ADULT_FISH_11, RC_LH_ADULT_FISH_12, RC_LH_ADULT_FISH_13, - RC_LH_ADULT_FISH_14, RC_LH_ADULT_FISH_15, RC_LH_ADULT_LOACH -}; +std::vector Rando::StaticData::GetGossipStoneLocations() { + std::vector gossipStoneLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_GOSSIP_STONE && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + gossipStoneLocations.push_back(location.GetRandomizerCheck()); + } + } + return gossipStoneLocations; +} -std::vector Rando::StaticData::overworldFishLocations = { - RC_DMC_UPPER_GROTTO_FISH, RC_DMT_STORMS_GROTTO_FISH, RC_HF_SOUTHEAST_GROTTO_FISH, - RC_HF_NEAR_MARKET_GROTTO_FISH, RC_HF_OPEN_GROTTO_FISH, RC_KAK_OPEN_GROTTO_FISH, - RC_KF_STORMS_GROTTO_FISH, RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RC_ZR_OPEN_GROTTO_FISH, - RC_ZD_FISH_1, RC_ZD_FISH_2, RC_ZD_FISH_3, RC_ZD_FISH_4, RC_ZD_FISH_5 -}; +std::vector Rando::StaticData::GetShopLocations() { + std::vector shopLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_SHOP && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + shopLocations.push_back(location.GetRandomizerCheck()); + } + } + return shopLocations; +} -typedef enum { - DUNGEON_DEKU_TREE = 0, - DUNGEON_DODONGOS_CAVERN, - DUNGEON_JABUJABUS_BELLY, - DUNGEON_FOREST_TEMPLE, - DUNGEON_FIRE_TEMPLE, - DUNGEON_WATER_TEMPLE, - DUNGEON_SPIRIT_TEMPLE, - DUNGEON_SHADOW_TEMPLE, - DUNGEON_BOTTOM_OF_THE_WELL, - DUNGEON_ICE_CAVERN, - DUNGEON_GANONS_CASTLE_SECOND_PART, - DUNGEON_GERUDO_TRAINING_GROUNDS, - DUNGEON_GERUDO_FORTRESS, - DUNGEON_GANONS_CASTLE_FIRST_PART, - DUNGEON_GANONS_CASTLE_FLOOR_BENEATH_BOSS_CHAMBER, - DUNGEON_GANONS_CASTLE_CRUMBLING, - DUNGEON_TREASURE_CHEST_SHOP, - DUNGEON_DEKU_TREE_BOSS_ROOM, - DUNGEON_DODONGOS_CAVERN_BOSS_ROOM, - DUNGEON_JABUJABUS_BELLY_BOSS_ROOM, -} DungeonId; +std::vector Rando::StaticData::GetOverworldLocations() { + std::vector overworldLocations = {}; + for (Location& location : locationTable) { + if ( + location.IsOverworld() && + location.GetRandomizerCheck() != RC_UNKNOWN_CHECK && + location.GetRandomizerCheck() != RC_TRIFORCE_COMPLETED && //not really an overworld check + location.GetRCType() != RCTYPE_FISH && //temp fix while locations are properly sorted out + location.GetRCType() != RCTYPE_CHEST_GAME && //this is supposed to be excluded + location.GetRCType() != RCTYPE_STATIC_HINT && + location.GetRCType() != RCTYPE_GOSSIP_STONE //don't put items on hints + ) { + overworldLocations.push_back(location.GetRandomizerCheck()); + } + } + return overworldLocations; +} -using namespace Rando; +std::vector Rando::StaticData::GetDungeonLocations() { + std::vector overworldLocations = {}; + for (Location& location : locationTable) { + if ( + location.IsDungeon() && + location.GetRCType() != RCTYPE_STATIC_HINT && + location.GetRCType() != RCTYPE_GOSSIP_STONE //don't put items on hints + ) { + overworldLocations.push_back(location.GetRandomizerCheck()); + } + } + return overworldLocations; +} -void Rando::StaticData::InitLocationTable() { // Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression +void Rando::StaticData::InitLocationTable() { // Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Hint Text Key Vanilla Item Spoiler Collection Check Collection Check Group Vanilla Progression // clang-format off - locationTable[RC_UNKNOWN_CHECK] = Location::Base(RC_UNKNOWN_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Invalid Location", "Invalid Location", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None()); + locationTable[RC_UNKNOWN_CHECK] = Location::Base(RC_UNKNOWN_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Invalid Location", "Invalid Location", RHT_NONE, RG_NONE); // Kokiri Forest - locationTable[RC_KF_KOKIRI_SWORD_CHEST] = Location::Chest(RC_KF_KOKIRI_SWORD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, 0x00, "Kokiri Sword Chest", RHT_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); - locationTable[RC_KF_MIDOS_TOP_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, 0x00, "Mido Top Left Chest", RHT_KF_MIDOS_TOP_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_TOP_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, 0x01, "Mido Top Right Chest", RHT_KF_MIDOS_TOP_RIGHT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_BOTTOM_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22914, 0x02, "Mido Bottom Left Chest", RHT_KF_MIDOS_BOTTOM_LEFT_CHEST, RG_GREG_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_MIDOS_BOTTOM_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22787, 0x03, "Mido Bottom Right Chest", RHT_KF_MIDOS_BOTTOM_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_STORMS_GROTTO_CHEST] = Location::Chest(RC_KF_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_GROTTOS, 22988, 0x0C, "Storms Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_KOKIRI_SWORD_CHEST] = Location::Chest(RC_KF_KOKIRI_SWORD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, 0x00, "Kokiri Sword Chest", RHT_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, true); + locationTable[RC_KF_MIDOS_TOP_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, 0x00, "Mido Top Left Chest", RHT_KF_MIDOS_TOP_LEFT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_KF_MIDOS_TOP_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, 0x01, "Mido Top Right Chest", RHT_KF_MIDOS_TOP_RIGHT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_KF_MIDOS_BOTTOM_LEFT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22914, 0x02, "Mido Bottom Left Chest", RHT_KF_MIDOS_BOTTOM_LEFT_CHEST, RG_GREG_RUPEE); + locationTable[RC_KF_MIDOS_BOTTOM_RIGHT_CHEST] = Location::Chest(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22787, 0x03, "Mido Bottom Right Chest", RHT_KF_MIDOS_BOTTOM_RIGHT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_KF_STORMS_GROTTO_CHEST] = Location::Chest(RC_KF_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_GROTTOS, 22988, 0x0C, "Storms Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE); // Lost Woods - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = Location::Chest(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, 0x14, "Near Shortcuts Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x3E, "Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x1F, "Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x21, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x60, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, 0x30, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, 0x31, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, 0x77, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), 0x33, "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), 0x79, "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x77, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, 0x7A, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = Location::Chest(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, 0x14, "Near Shortcuts Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE); + locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(22), true); + locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO), true); + locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, SpoilerCollectionCheck::ItemGetInf(49), true); + locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(23), true); + locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(29), true); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT)); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT)); + locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), true); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR)); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT)); + locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), true); + locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), true); // Sacred Forest Meadow - locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), 0x39, "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), 0x3A, "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR)); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT)); // Hyrule Field - locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, 0x0C, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0x43), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::GrottoScrub(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), 0x3E, "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, { Category::cDekuScrub, Category::cDekuScrubUpgrades }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); + locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE); + locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE); + locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE); + locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0x43)); + locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::Base(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), true); // Lake Hylia - locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x3E, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x38, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_HYRULE_LOACH] = Location::Base(RC_LH_HYRULE_LOACH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, 0x00, "Hyrule Loach Reward", RHT_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CAUGHT_LOACH), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x3E, "Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, 0x25, "Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x15, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, 0x58, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LAKE_HYLIA, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, true); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), 0x30, "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), 0x37, "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), 0x33, "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), true); + locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), true); + locationTable[RC_LH_HYRULE_LOACH] = Location::Base(RC_LH_HYRULE_LOACH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Hyrule Loach Reward", RHT_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CAUGHT_LOACH)); + locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(16), true); + locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), true); + locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, SpoilerCollectionCheck::EventChkInf(0x31), true); + locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, SpoilerCollectionCheck::Chest(0x57, 0x1F), true); + locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT)); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT)); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER)); // Gerudo Valley - locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_GERUDO_VALLEY, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, 0x22, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), 0x39, "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), 0x3A, "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), true); + locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR)); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT)); // Gerudo Fortress - locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x3E, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_190), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, 0x30, "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, true); + locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_190), true); + locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(15), true); // RandoTodo: Do we replace these with the RC_HIDEOUT keys or keep these? - locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GERUDO_FORTRESS, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, 0x3A, "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, RCAREA_GERUDO_FORTRESS, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, { Category::cVanillaGFSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); + locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS), true); + locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); + locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); + locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); + locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); // Haunted Wasteland - locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, 0x03, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)); // Desert Colossus - locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), 0x39, "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), 0x3A, "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR)); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT)); // Market - locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0x0A, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x33, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, 0x3E, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, 0x3E, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(INFTABLE_191), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x60, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, 0x0F, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, RCAREA_MARKET, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, 0xFF, "Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, { Category::cChestMinigame }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, SpoilerCollectionCheck::ItemGetInf(27), true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::ItemGetInf(17), true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(18), true); + locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_191), true); + locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), true); + locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), true); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5)); // Hyrule Castle - locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, 0x47, "Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, {}, SpoilerCollectionCheck::EventChkInf(0x12), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, 0x0B, "Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x40), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); + locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, "Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, SpoilerCollectionCheck::EventChkInf(0x12), true); + locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, "Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, SpoilerCollectionCheck::EventChkInf(0x40), true); // Kakariko - locationTable[RC_KAK_REDEAD_GROTTO_CHEST] = Location::Chest(RC_KAK_REDEAD_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, 0x0A, "Redead Grotto Chest", RHT_KAK_REDEAD_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_OPEN_GROTTO_CHEST] = Location::Chest(RC_KAK_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, 0x08, "Open Grotto Chest", RHT_KAK_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x45, "10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x39, "20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, {}, SpoilerCollectionCheck::EventChkInf(0xDB), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x46, "30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x03, "40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, 0x3E, "100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x3E, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, 0x30, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x20, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, 0x4E, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x1D, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0F, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, 0x0E, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, { Category::cAdultTrade }, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_IMPAS_HOUSE_FREESTANDING_POH] = Location::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_IMPAS_HOUSE, 262, 0x01, "Impas House Freestanding PoH", RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_KAK_WINDMILL_FREESTANDING_POH] = Location::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 262, 0x01, "Windmill Freestanding PoH", RHT_KAK_WINDMILL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_KAK_REDEAD_GROTTO_CHEST] = Location::Chest(RC_KAK_REDEAD_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, 0x0A, "Redead Grotto Chest", RHT_KAK_REDEAD_GROTTO_CHEST, RG_HUGE_RUPEE); + locationTable[RC_KAK_OPEN_GROTTO_CHEST] = Location::Chest(RC_KAK_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, 0x08, "Open Grotto Chest", RHT_KAK_OPEN_GROTTO_CHEST, RG_RED_RUPEE); + locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDA), true); + locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, SpoilerCollectionCheck::EventChkInf(0xDB), true); + locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDC), true); + locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, SpoilerCollectionCheck::EventChkInf(0xDD)); + locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xDE), true); + locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)); + locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(21), true); + locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), true); + locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, SpoilerCollectionCheck::ItemGetInf(48), true); + locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), true); + locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, SpoilerCollectionCheck::ItemGetInf(44), true); + locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::ItemGetInf(12), true); + locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, SpoilerCollectionCheck::ItemGetInf(46), true); + locationTable[RC_KAK_IMPAS_HOUSE_FREESTANDING_POH] = Location::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_IMPAS_HOUSE, 262, 0x01, "Impas House Freestanding PoH", RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_KAK_WINDMILL_FREESTANDING_POH] = Location::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 262, 0x01, "Windmill Freestanding PoH", RHT_KAK_WINDMILL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Graveyard - locationTable[RC_GRAVEYARD_SHIELD_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 21824, 0x00, "Shield Grave Chest", RHT_GRAVEYARD_SHIELD_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_REDEAD_GRAVE, -22592, 0x00, "Heart Piece Grave Chest", RHT_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST] = Location::Chest(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_ROYAL_FAMILYS_TOMB, -32736, 0x00, "Composers Grave Chest", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_HOOKSHOT_CHEST] = Location::Chest(RC_GRAVEYARD_HOOKSHOT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, 0x00, "Hookshot Chest", RHT_GRAVEYARD_HOOKSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, 0x04, "Freestanding PoH", RHT_GRAVEYARD_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, 0x07, "Dampe Race Freestanding PoH", RHT_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = Location::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, 0x19, "Dampe Gravedigging Tour", RHT_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 21824, 0x00, "Shield Grave Chest", RHT_GRAVEYARD_SHIELD_GRAVE_CHEST, RG_HYLIAN_SHIELD); + locationTable[RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = Location::Chest(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_REDEAD_GRAVE, -22592, 0x00, "Heart Piece Grave Chest", RHT_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, RG_PIECE_OF_HEART, true); + locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST] = Location::Chest(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ROYAL_FAMILYS_TOMB, -32736, 0x00, "Composers Grave Chest", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, RG_BOMBS_5); + locationTable[RC_GRAVEYARD_HOOKSHOT_CHEST] = Location::Chest(RC_GRAVEYARD_HOOKSHOT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, 0x00, "Hookshot Chest", RHT_GRAVEYARD_HOOKSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, true); + locationTable[RC_GRAVEYARD_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, 0x04, "Freestanding PoH", RHT_GRAVEYARD_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, 0x07, "Dampe Race Freestanding PoH", RHT_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = Location::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, 0x19, "Dampe Gravedigging Tour", RHT_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RG_PIECE_OF_HEART, true); // Death Mountain - locationTable[RC_DMT_CHEST] = Location::Chest(RC_DMT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, 0x01, "Chest", RHT_DMT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_STORMS_GROTTO_CHEST] = Location::Chest(RC_DMT_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, 0x17, "Storms Grotto Chest", RHT_DMT_STORMS_GROTTO_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x23, "Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x26, "Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, 0x57, "Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMT_FREESTANDING_POH] = Location::Collectable(RC_DMT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, 7686, 0x1E, "Freestanding PoH", RHT_DMT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); + locationTable[RC_DMT_CHEST] = Location::Chest(RC_DMT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, 0x01, "Chest", RHT_DMT_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_DMT_STORMS_GROTTO_CHEST] = Location::Chest(RC_DMT_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, 0x17, "Storms Grotto Chest", RHT_DMT_STORMS_GROTTO_CHEST, RG_HUGE_RUPEE); + locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD), true); + locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS), true); + locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK), true); + locationTable[RC_DMT_FREESTANDING_POH] = Location::Collectable(RC_DMT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, 7686, 0x1E, "Freestanding PoH", RHT_DMT_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Goron City - locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x34, "Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::InfTable(INFTABLE_11E), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x2C, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, {}, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x54, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_GORON_CITY, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY, true); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), 0x30, "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), 0x37, "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), 0x33, "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_GORON_CITY, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, 0x51, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, { Category::cMerchant }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE); + locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::InfTable(INFTABLE_11E), true); + locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), true); + locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), true); + locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT)); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT)); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER)); + locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)); // Death Mountain Crater - locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, 0x37, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), 0x30, "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), 0x37, "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), 0x33, "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); + locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20); + locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB)); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT)); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT)); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER)); // Zoras River - locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, 0x16, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD1), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD2), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD4), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD3), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD5), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x3E, "Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, 0x76, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, true); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), 0x39, "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), 0x3A, "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE); + locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), true); + locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD1)); + locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD2)); + locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD4)); + locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD3)); + locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD5)); + locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD6), true); + locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD0), true); + locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR)); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT)); // Zoras Domain - locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x37, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::EventChkInf(0x38), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x2D, "King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, RCAREA_ZORAS_DOMAIN, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, 0x24, "Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, { Category::cAdultTrade }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, true); + locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::EventChkInf(0x38), true); + locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), true); + locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), true); // Zora's Fountain - locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); + locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Lon Lon Ranch - locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, 0x14, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(2), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LON_LON_RANCH, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), 0x30, "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), 0x37, "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), 0x33, "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true); + locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT)); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT)); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER)); // Dungeons // Deku Tree Vanilla - locationTable[RC_DEKU_TREE_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "Map Chest", RHT_DEKU_TREE_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2050, 0x02, "Compass Chest", RHT_DEKU_TREE_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22790, 0x06, "Compass Room Side Chest", RHT_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22788, 0x04, "Basement Chest", RHT_DEKU_TREE_BASEMENT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 161, 0x01, "Slingshot Chest", RHT_DEKU_TREE_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "Slingshot Room Side Chest", RHT_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "Map Chest", RHT_DEKU_TREE_MAP_CHEST, RG_DEKU_TREE_MAP, true); + locationTable[RC_DEKU_TREE_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2050, 0x02, "Compass Chest", RHT_DEKU_TREE_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, true); + locationTable[RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22790, 0x06, "Compass Room Side Chest", RHT_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RG_RECOVERY_HEART); + locationTable[RC_DEKU_TREE_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22788, 0x04, "Basement Chest", RHT_DEKU_TREE_BASEMENT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_DEKU_TREE_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 161, 0x01, "Slingshot Chest", RHT_DEKU_TREE_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, true); + locationTable[RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = Location::Chest(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "Slingshot Room Side Chest", RHT_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RG_RECOVERY_HEART); // Deku Tree MQ - locationTable[RC_DEKU_TREE_MQ_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "MQ Map Chest", RHT_DEKU_TREE_MQ_MAP_CHEST, RG_DEKU_TREE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2049, 0x01, "MQ Compass Chest", RHT_DEKU_TREE_MQ_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 4262, 0x06, "MQ Slingshot Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31454, 0x02, "MQ Slingshot Room Back Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DEKU_TREE, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DEKU_TREE, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, 0x34, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_MQ_MAP_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2083, 0x03, "MQ Map Chest", RHT_DEKU_TREE_MQ_MAP_CHEST, RG_DEKU_TREE_MAP, true); + locationTable[RC_DEKU_TREE_MQ_COMPASS_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_DEKU_TREE, 2049, 0x01, "MQ Compass Chest", RHT_DEKU_TREE_MQ_COMPASS_CHEST, RG_DEKU_TREE_COMPASS, true); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 4262, 0x06, "MQ Slingshot Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_CHEST, RG_PROGRESSIVE_SLINGSHOT, true); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31454, 0x02, "MQ Slingshot Room Back Chest", RHT_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, RG_DEKU_SHIELD); + locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD); + locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART); + locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB)); // Dodongo's Cavern Shared - locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5); // Dodongo's Cavern Vanilla - locationTable[RC_DODONGOS_CAVERN_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2088, 0x08, "Map Chest", RHT_DODONGOS_CAVERN_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2053, 0x05, "Compass Chest", RHT_DODONGOS_CAVERN_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, 0x30, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2088, 0x08, "Map Chest", RHT_DODONGOS_CAVERN_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, true); + locationTable[RC_DODONGOS_CAVERN_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2053, 0x05, "Compass Chest", RHT_DODONGOS_CAVERN_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, true); + locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE); + locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); + locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT)); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS)); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT)); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY)); // Dodongo's Cavern MQ - locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 6149, 0x05, "MQ Compass Chest", RHT_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_DODONGOS_CAVERN, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, 0x31, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, 0x33, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, 0x34, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_DODONGOS_CAVERN, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, 0x39, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); + locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, true); + locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); + locationTable[RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 6149, 0x05, "MQ Compass Chest", RHT_DODONGOS_CAVERN_MQ_COMPASS_CHEST, RG_DODONGOS_CAVERN_COMPASS, true); + locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE); + locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR)); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT)); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE)); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS)); // Jabu-Jabu's Belly Vanilla - locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, 0x30, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); + locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, true); + locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, true); + locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB)); // Jabu-Jabu's Belly MQ - locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20546, 0x02, "MQ Second Room Lower Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -18432, 0x00, "MQ Compass Chest", RHT_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -30457, 0x07, "MQ Second Room Upper Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32696, 0x08, "MQ Basement Near Switches Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -32668, 0x04, "MQ Basement Near Vines Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, -31446, 0x0A, "MQ Near Boss Chest", RHT_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 28905, 0x09, "MQ Falling Like Like Room Chest", RHT_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RG_DEKU_STICK_1, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 20545, 0x01, "MQ Boomerang Room Small Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_BOX, SCENE_JABU_JABU, 4294, 0x06, "MQ Boomerang Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RG_BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5); + locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 20546, 0x02, "MQ Second Room Lower Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, RG_DEKU_NUTS_5); + locationTable[RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_JABU_JABU, -18432, 0x00, "MQ Compass Chest", RHT_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, true); + locationTable[RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -30457, 0x07, "MQ Second Room Upper Chest", RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RG_RECOVERY_HEART); + locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32696, 0x08, "MQ Basement Near Switches Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, RG_DEKU_NUTS_5); + locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32668, 0x04, "MQ Basement Near Vines Chest", RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, RG_BOMBCHU_10); + locationTable[RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -31446, 0x0A, "MQ Near Boss Chest", RHT_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, RG_DEKU_SHIELD); + locationTable[RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 28905, 0x09, "MQ Falling Like Like Room Chest", RHT_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, RG_DEKU_STICK_1); + locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 20545, 0x01, "MQ Boomerang Room Small Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, RG_DEKU_NUTS_5); + locationTable[RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 4294, 0x06, "MQ Boomerang Chest", RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, RG_BOOMERANG, true); // Forest Temple Vanilla - locationTable[RC_FOREST_TEMPLE_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22595, 0x03, "First Room Chest", RHT_FOREST_TEMPLE_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "First Stalfos Chest", RHT_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22789, 0x05, "Raised Island Courtyard Chest", RHT_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6177, 0x01, "Map Chest", RHT_FOREST_TEMPLE_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_WELL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "Well Chest", RHT_FOREST_TEMPLE_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22855, 0x07, "Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_EYE_SWITCH_CHEST] = Location::Chest(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30364, 0x04, "Eye Switch Chest", RHT_FOREST_TEMPLE_EYE_SWITCH_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "Boss Key Chest", RHT_FOREST_TEMPLE_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_FLOORMASTER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "Floormaster Chest", RHT_FOREST_TEMPLE_FLOORMASTER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "Bow Chest", RHT_FOREST_TEMPLE_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_RED_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RED_POE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30797, 0x0D, "Red Poe Chest", RHT_FOREST_TEMPLE_RED_POE_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BLUE_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BLUE_POE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "Blue Poe Chest", RHT_FOREST_TEMPLE_BLUE_POE_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "Basement Chest", RHT_FOREST_TEMPLE_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_FOREST_TEMPLE_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22595, 0x03, "First Room Chest", RHT_FOREST_TEMPLE_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "First Stalfos Chest", RHT_FOREST_TEMPLE_FIRST_STALFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22789, 0x05, "Raised Island Courtyard Chest", RHT_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RG_RECOVERY_HEART); + locationTable[RC_FOREST_TEMPLE_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6177, 0x01, "Map Chest", RHT_FOREST_TEMPLE_MAP_CHEST, RG_FOREST_TEMPLE_MAP, true); + locationTable[RC_FOREST_TEMPLE_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_WELL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "Well Chest", RHT_FOREST_TEMPLE_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22855, 0x07, "Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_10); + locationTable[RC_FOREST_TEMPLE_EYE_SWITCH_CHEST] = Location::Chest(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30364, 0x04, "Eye Switch Chest", RHT_FOREST_TEMPLE_EYE_SWITCH_CHEST, RG_ARROWS_30); + locationTable[RC_FOREST_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "Boss Key Chest", RHT_FOREST_TEMPLE_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, true); + locationTable[RC_FOREST_TEMPLE_FLOORMASTER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "Floormaster Chest", RHT_FOREST_TEMPLE_FLOORMASTER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BOW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "Bow Chest", RHT_FOREST_TEMPLE_BOW_CHEST, RG_PROGRESSIVE_BOW, true); + locationTable[RC_FOREST_TEMPLE_RED_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_RED_POE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30797, 0x0D, "Red Poe Chest", RHT_FOREST_TEMPLE_RED_POE_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_BLUE_POE_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BLUE_POE_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "Blue Poe Chest", RHT_FOREST_TEMPLE_BLUE_POE_CHEST, RG_FOREST_TEMPLE_COMPASS, true); + locationTable[RC_FOREST_TEMPLE_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_BASEMENT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "Basement Chest", RHT_FOREST_TEMPLE_BASEMENT_CHEST, RG_ARROWS_5); // Forest Temple MQ - locationTable[RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30653, 0x03, "MQ First Room Chest", RHT_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "MQ Wolfos Chest", RHT_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOW_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "MQ Bow Chest", RHT_FOREST_TEMPLE_MQ_BOW_CHEST, RG_PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22593, 0x01, "MQ Raised Island Courtyard Lower Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22597, 0x05, "MQ Raised Island Courtyard Upper Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WELL_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "MQ Well Chest", RHT_FOREST_TEMPLE_MQ_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6189, 0x0D, "MQ Map Chest", RHT_FOREST_TEMPLE_MQ_MAP_CHEST, RG_FOREST_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "MQ Compass Chest", RHT_FOREST_TEMPLE_MQ_COMPASS_CHEST, RG_FOREST_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30426, 0x06, "MQ Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "MQ Basement Chest", RHT_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_REDEAD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "MQ Redead Chest", RHT_FOREST_TEMPLE_MQ_REDEAD_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FOREST_TEMPLE, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "MQ Boss Key Chest", RHT_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); + locationTable[RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30653, 0x03, "MQ First Room Chest", RHT_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, RG_FOREST_TEMPLE_SMALL_KEY); + locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30784, 0x00, "MQ Wolfos Chest", RHT_FOREST_TEMPLE_MQ_WOLFOS_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_MQ_BOW_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOW_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -20340, 0x0C, "MQ Bow Chest", RHT_FOREST_TEMPLE_MQ_BOW_CHEST, RG_PROGRESSIVE_BOW, true); + locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22593, 0x01, "MQ Raised Island Courtyard Lower Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22597, 0x05, "MQ Raised Island Courtyard Upper Chest", RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_WELL_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22601, 0x09, "MQ Well Chest", RHT_FOREST_TEMPLE_MQ_WELL_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6189, 0x0D, "MQ Map Chest", RHT_FOREST_TEMPLE_MQ_MAP_CHEST, RG_FOREST_TEMPLE_MAP, true); + locationTable[RC_FOREST_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 6159, 0x0F, "MQ Compass Chest", RHT_FOREST_TEMPLE_MQ_COMPASS_CHEST, RG_FOREST_TEMPLE_COMPASS, true); + locationTable[RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, -30426, 0x06, "MQ Falling Ceiling Room Chest", RHT_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, RG_ARROWS_5); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 22827, 0x0B, "MQ Basement Chest", RHT_FOREST_TEMPLE_MQ_BASEMENT_CHEST, RG_ARROWS_5); + locationTable[RC_FOREST_TEMPLE_MQ_REDEAD_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 30786, 0x02, "MQ Redead Chest", RHT_FOREST_TEMPLE_MQ_REDEAD_CHEST, RG_FOREST_TEMPLE_SMALL_KEY, true); + locationTable[RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_FOREST_TEMPLE, 10222, 0x0E, "MQ Boss Key Chest", RHT_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FOREST_TEMPLE_BOSS_KEY, true); // Fire Temple Vanilla - locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "Near Boss Chest", RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_FLARE_DANCER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 31936, 0x00, "Flare Dancer Chest", RHT_FIRE_TEMPLE_FLARE_DANCER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10220, 0x0C, "Boss Key Chest", RHT_FIRE_TEMPLE_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22594, 0x02, "Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22596, 0x04, "Big Lava Room Lower Open Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22595, 0x03, "Boulder Maze Lower Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22598, 0x06, "Boulder Maze Upper Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "Boulder Maze Side Room Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22603, 0x0B, "Boulder Maze Shortcut Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_SCARECROW_CHEST] = Location::Chest(RC_FIRE_TEMPLE_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23245, 0x0D, "Scarecrow Chest", RHT_FIRE_TEMPLE_SCARECROW_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2090, 0x0A, "Map Chest", RHT_FIRE_TEMPLE_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2055, 0x07, "Compass Chest", RHT_FIRE_TEMPLE_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST] = Location::Chest(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22601, 0x09, "Highest Goron Chest", RHT_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 421, 0x05, "Megaton Hammer Chest", RHT_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "Near Boss Chest", RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_FLARE_DANCER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 31936, 0x00, "Flare Dancer Chest", RHT_FIRE_TEMPLE_FLARE_DANCER_CHEST, RG_BOMBS_10); + locationTable[RC_FIRE_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10220, 0x0C, "Boss Key Chest", RHT_FIRE_TEMPLE_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, true); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22594, 0x02, "Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22596, 0x04, "Big Lava Room Lower Open Door Chest", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22595, 0x03, "Boulder Maze Lower Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22598, 0x06, "Boulder Maze Upper Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "Boulder Maze Side Room Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = Location::Chest(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22603, 0x0B, "Boulder Maze Shortcut Chest", RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_SCARECROW_CHEST] = Location::Chest(RC_FIRE_TEMPLE_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23245, 0x0D, "Scarecrow Chest", RHT_FIRE_TEMPLE_SCARECROW_CHEST, RG_HUGE_RUPEE); + locationTable[RC_FIRE_TEMPLE_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2090, 0x0A, "Map Chest", RHT_FIRE_TEMPLE_MAP_CHEST, RG_FIRE_TEMPLE_MAP, true); + locationTable[RC_FIRE_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2055, 0x07, "Compass Chest", RHT_FIRE_TEMPLE_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, true); + locationTable[RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST] = Location::Chest(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22601, 0x09, "Highest Goron Chest", RHT_FIRE_TEMPLE_HIGHEST_GORON_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 421, 0x05, "Megaton Hammer Chest", RHT_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, true); // Fire Temple MQ - locationTable[RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22599, 0x07, "MQ Near Boss Chest", RHT_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 4512, 0x00, "MQ Megaton Hammer Chest", RHT_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2059, 0x0B, "MQ Compass Chest", RHT_FIRE_TEMPLE_MQ_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23747, 0x03, "MQ Lizalfos Maze Lower Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23782, 0x06, "MQ Lizalfos Maze Upper Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = Location::Chest(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22597, 0x05, "MQ Chest on Fire", RHT_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 30018, 0x02, "MQ Map Room Side Chest", RHT_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2092, 0x0C, "MQ Map Chest", RHT_FIRE_TEMPLE_MQ_MAP_CHEST, RG_FIRE_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10212, 0x04, "MQ Boss Key Chest", RHT_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "MQ Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "MQ Lizalfos Maze Side Room Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_FIRE_TEMPLE, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, 7185, 0x1C, "MQ Freestanding Key", RHT_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RG_FIRE_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); + locationTable[RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22599, 0x07, "MQ Near Boss Chest", RHT_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 4512, 0x00, "MQ Megaton Hammer Chest", RHT_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, RG_MEGATON_HAMMER, true); + locationTable[RC_FIRE_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2059, 0x0B, "MQ Compass Chest", RHT_FIRE_TEMPLE_MQ_COMPASS_CHEST, RG_FIRE_TEMPLE_COMPASS, true); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23747, 0x03, "MQ Lizalfos Maze Lower Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, RG_BOMBS_10); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 23782, 0x06, "MQ Lizalfos Maze Upper Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, RG_BOMBS_10); + locationTable[RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = Location::Chest(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22597, 0x05, "MQ Chest on Fire", RHT_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 30018, 0x02, "MQ Map Room Side Chest", RHT_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, RG_HYLIAN_SHIELD); + locationTable[RC_FIRE_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 2092, 0x0C, "MQ Map Chest", RHT_FIRE_TEMPLE_MQ_MAP_CHEST, RG_FIRE_TEMPLE_MAP, true); + locationTable[RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 10212, 0x04, "MQ Boss Key Chest", RHT_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, RG_FIRE_TEMPLE_BOSS_KEY, true); + locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22593, 0x01, "MQ Big Lava Room Blocked Door Chest", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = Location::Chest(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_FIRE_TEMPLE, 22600, 0x08, "MQ Lizalfos Maze Side Room Chest", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RG_FIRE_TEMPLE_SMALL_KEY, true); + locationTable[RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, 7185, 0x1C, "MQ Freestanding Key", RHT_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RG_FIRE_TEMPLE_SMALL_KEY, true); // Water Temple Vanilla - locationTable[RC_WATER_TEMPLE_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6178, 0x02, "Map Chest", RHT_WATER_TEMPLE_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 2057, 0x09, "Compass Chest", RHT_WATER_TEMPLE_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_TORCHES_CHEST] = Location::Chest(RC_WATER_TEMPLE_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 30785, 0x01, "Torches Chest", RHT_WATER_TEMPLE_TORCHES_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_DRAGON_CHEST] = Location::Chest(RC_WATER_TEMPLE_DRAGON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22602, 0x0A, "Dragon Chest", RHT_WATER_TEMPLE_DRAGON_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22600, 0x08, "Central Bow Target Chest", RHT_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22598, 0x06, "Central Pillar Chest", RHT_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_CRACKED_WALL_CHEST] = Location::Chest(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22592, 0x00, "Cracked Wall Chest", RHT_WATER_TEMPLE_CRACKED_WALL_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "Boss Key Chest", RHT_WATER_TEMPLE_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_LONGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 295, 0x07, "Longshot Chest", RHT_WATER_TEMPLE_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_RIVER_CHEST] = Location::Chest(RC_WATER_TEMPLE_RIVER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22595, 0x03, "River Chest", RHT_WATER_TEMPLE_RIVER_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6178, 0x02, "Map Chest", RHT_WATER_TEMPLE_MAP_CHEST, RG_WATER_TEMPLE_MAP, true); + locationTable[RC_WATER_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 2057, 0x09, "Compass Chest", RHT_WATER_TEMPLE_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, true); + locationTable[RC_WATER_TEMPLE_TORCHES_CHEST] = Location::Chest(RC_WATER_TEMPLE_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 30785, 0x01, "Torches Chest", RHT_WATER_TEMPLE_TORCHES_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_DRAGON_CHEST] = Location::Chest(RC_WATER_TEMPLE_DRAGON_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22602, 0x0A, "Dragon Chest", RHT_WATER_TEMPLE_DRAGON_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22600, 0x08, "Central Bow Target Chest", RHT_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22598, 0x06, "Central Pillar Chest", RHT_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_CRACKED_WALL_CHEST] = Location::Chest(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22592, 0x00, "Cracked Wall Chest", RHT_WATER_TEMPLE_CRACKED_WALL_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "Boss Key Chest", RHT_WATER_TEMPLE_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, true); + locationTable[RC_WATER_TEMPLE_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_LONGSHOT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 295, 0x07, "Longshot Chest", RHT_WATER_TEMPLE_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, true); + locationTable[RC_WATER_TEMPLE_RIVER_CHEST] = Location::Chest(RC_WATER_TEMPLE_RIVER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 22595, 0x03, "River Chest", RHT_WATER_TEMPLE_RIVER_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); // Water Temple MQ - locationTable[RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -30650, 0x06, "MQ Central Pillar Chest", RHT_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", RHT_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -20192, 0x00, "MQ Longshot Chest", RHT_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6145, 0x01, "MQ Compass Chest", RHT_WATER_TEMPLE_MQ_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_WATER_TEMPLE, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -18398, 0x02, "MQ Map Chest", RHT_WATER_TEMPLE_MQ_MAP_CHEST, RG_WATER_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_WATER_TEMPLE, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, 273, 0x01, "MQ Freestanding Key", RHT_WATER_TEMPLE_MQ_FREESTANDING_KEY, RG_WATER_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); + locationTable[RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -30650, 0x06, "MQ Central Pillar Chest", RHT_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, RG_WATER_TEMPLE_SMALL_KEY, true); + locationTable[RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", RHT_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, RG_WATER_TEMPLE_BOSS_KEY, true); + locationTable[RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -20192, 0x00, "MQ Longshot Chest", RHT_WATER_TEMPLE_MQ_LONGSHOT_CHEST, RG_PROGRESSIVE_HOOKSHOT, true); + locationTable[RC_WATER_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, 6145, 0x01, "MQ Compass Chest", RHT_WATER_TEMPLE_MQ_COMPASS_CHEST, RG_WATER_TEMPLE_COMPASS, true); + locationTable[RC_WATER_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_WATER_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_WATER_TEMPLE, -18398, 0x02, "MQ Map Chest", RHT_WATER_TEMPLE_MQ_MAP_CHEST, RG_WATER_TEMPLE_MAP, true); + locationTable[RC_WATER_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, 273, 0x01, "MQ Freestanding Key", RHT_WATER_TEMPLE_MQ_FREESTANDING_KEY, RG_WATER_TEMPLE_SMALL_KEY, true); // Spirit Temple Shared - locationTable[RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 1707, 0x0B, "Silver Gauntlets Chest", RHT_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 13673, 0x09, "Mirror Shield Chest", RHT_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RG_MIRROR_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 1707, 0x0B, "Silver Gauntlets Chest", RHT_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, true); + locationTable[RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_DESERT_COLOSSUS, 13673, 0x09, "Mirror Shield Chest", RHT_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, RG_MIRROR_SHIELD, true); // Spirit Temple Vanilla - locationTable[RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 21800, 0x08, "Child Bridge Chest", RHT_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30656, 0x00, "Child Early Torches Chest", RHT_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 14340, 0x04, "Compass Chest", RHT_SPIRIT_TEMPLE_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22599, 0x07, "Early Adult Right Chest", RHT_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30451, 0x0D, "First Mirror Left Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -28786, 0x0E, "First Mirror Right Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18397, 0x03, "Map Chest", RHT_SPIRIT_TEMPLE_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32666, 0x06, "Child Climb North Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -31444, 0x0C, "Child Climb East Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30655, 0x01, "Sun Block Room Chest", RHT_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30654, 0x02, "Statue Room Hand Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "Statue Room Northeast Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22597, 0x05, "Near Four Armos Chest", RHT_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26900, 0x14, "Hallway Right Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26901, 0x15, "Hallway Left Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10218, 0x0A, "Boss Key Chest", RHT_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_TOPMOST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -29454, 0x12, "Topmost Chest", RHT_SPIRIT_TEMPLE_TOPMOST_CHEST, RG_BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 21800, 0x08, "Child Bridge Chest", RHT_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, RG_DEKU_SHIELD); + locationTable[RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30656, 0x00, "Child Early Torches Chest", RHT_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 14340, 0x04, "Compass Chest", RHT_SPIRIT_TEMPLE_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, true); + locationTable[RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22599, 0x07, "Early Adult Right Chest", RHT_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30451, 0x0D, "First Mirror Left Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, RG_ICE_TRAP); + locationTable[RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -28786, 0x0E, "First Mirror Right Chest", RHT_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18397, 0x03, "Map Chest", RHT_SPIRIT_TEMPLE_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, true); + locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32666, 0x06, "Child Climb North Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10); + locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -31444, 0x0C, "Child Climb East Chest", RHT_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, RG_DEKU_SHIELD); + locationTable[RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30655, 0x01, "Sun Block Room Chest", RHT_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30654, 0x02, "Statue Room Hand Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "Statue Room Northeast Chest", RHT_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 22597, 0x05, "Near Four Armos Chest", RHT_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26900, 0x14, "Hallway Right Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26901, 0x15, "Hallway Left Invisible Chest", RHT_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10218, 0x0A, "Boss Key Chest", RHT_SPIRIT_TEMPLE_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_TOPMOST_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -29454, 0x12, "Topmost Chest", RHT_SPIRIT_TEMPLE_TOPMOST_CHEST, RG_BOMBS_20, true); // Spirit Temple MQ - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 20602, 0x1A, "MQ Entrance Front Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32641, 0x1F, "MQ Entrance Back Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30629, 0x1B, "MQ Entrance Front Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30626, 0x1E, "MQ Entrance Back Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30627, 0x1D, "MQ Child Hammer Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 2080, 0x00, "MQ Map Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 30792, 0x08, "MQ Map Room Enemy Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 28774, 0x06, "MQ Child Climb North Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30644, 0x0C, "MQ Child Climb South Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18429, 0x03, "MQ Compass Chest", RHT_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "MQ Statue Room Lullaby Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26882, 0x02, "MQ Statue Room Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30628, 0x1C, "MQ Silver Block Hallway Chest", RHT_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30463, 0x01, "MQ Sun Block Room Chest", RHT_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 23207, 0x07, "MQ Symphony Room Chest", RHT_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31396, 0x04, "MQ Leever Room Chest", RHT_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 24472, 0x19, "MQ Beamos Room Chest", RHT_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31097, 0x18, "MQ Chest Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", RHT_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SPIRIT_TEMPLE, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26706, 0x12, "MQ Mirror Puzzle Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 20602, 0x1A, "MQ Entrance Front Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, RG_BOMBCHU_10); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -32641, 0x1F, "MQ Entrance Back Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, RG_BOMBCHU_10); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30629, 0x1B, "MQ Entrance Front Right Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30626, 0x1E, "MQ Entrance Back Left Chest", RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30627, 0x1D, "MQ Child Hammer Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 2080, 0x00, "MQ Map Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_CHEST, RG_SPIRIT_TEMPLE_MAP, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 30792, 0x08, "MQ Map Room Enemy Chest", RHT_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 28774, 0x06, "MQ Child Climb North Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, RG_BOMBCHU_10); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30644, 0x0C, "MQ Child Climb South Chest", RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -18429, 0x03, "MQ Compass Chest", RHT_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, RG_SPIRIT_TEMPLE_COMPASS, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30577, 0x0F, "MQ Statue Room Lullaby Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26882, 0x02, "MQ Statue Room Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30628, 0x1C, "MQ Silver Block Hallway Chest", RHT_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, -30463, 0x01, "MQ Sun Block Room Chest", RHT_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 23207, 0x07, "MQ Symphony Room Chest", RHT_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31396, 0x04, "MQ Leever Room Chest", RHT_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 24472, 0x19, "MQ Beamos Room Chest", RHT_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RG_RECOVERY_HEART); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 31097, 0x18, "MQ Chest Switch Chest", RHT_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, RG_ICE_TRAP); + locationTable[RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 10213, 0x05, "MQ Boss Key Chest", RHT_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SPIRIT_TEMPLE_BOSS_KEY, true); + locationTable[RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = Location::Chest(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SPIRIT_TEMPLE, 26706, 0x12, "MQ Mirror Puzzle Invisible Chest", RHT_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, RG_SPIRIT_TEMPLE_SMALL_KEY, true); // Shadow Temple Vanilla - locationTable[RC_SHADOW_TEMPLE_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6177, 0x01, "Map Chest", RHT_SHADOW_TEMPLE_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "Hover Boots Chest", RHT_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6147, 0x03, "Compass Chest", RHT_SHADOW_TEMPLE_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22594, 0x02, "Early Silver Rupee Chest", RHT_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26998, 0x16, "Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x06, "Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x04, "Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "Invisible Spikes Chest", RHT_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26965, 0x15, "Wind Hint Chest", RHT_SHADOW_TEMPLE_WIND_HINT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "After Wind Enemy Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26708, 0x14, "After Wind Hidden Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "Spike Walls Left Chest", RHT_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "Boss Key Chest", RHT_SHADOW_TEMPLE_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30797, 0x0D, "Invisible Floormaster Chest", RHT_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 273, 0x01, "Freestanding Key", RHT_SHADOW_TEMPLE_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6177, 0x01, "Map Chest", RHT_SHADOW_TEMPLE_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, true); + locationTable[RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "Hover Boots Chest", RHT_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, true); + locationTable[RC_SHADOW_TEMPLE_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6147, 0x03, "Compass Chest", RHT_SHADOW_TEMPLE_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, true); + locationTable[RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22594, 0x02, "Early Silver Rupee Chest", RHT_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26998, 0x16, "Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_ARROWS_30); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x06, "Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x04, "Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "Invisible Spikes Chest", RHT_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26965, 0x15, "Wind Hint Chest", RHT_SHADOW_TEMPLE_WIND_HINT_CHEST, RG_ARROWS_10); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "After Wind Enemy Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26708, 0x14, "After Wind Hidden Chest", RHT_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "Spike Walls Left Chest", RHT_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "Boss Key Chest", RHT_SHADOW_TEMPLE_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, true); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30797, 0x0D, "Invisible Floormaster Chest", RHT_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 273, 0x01, "Freestanding Key", RHT_SHADOW_TEMPLE_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, true); // Shadow Temple MQ - locationTable[RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6145, 0x01, "MQ Compass Chest", RHT_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "MQ Hover Boots Chest", RHT_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30787, 0x03, "MQ Early Gibdos Chest", RHT_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 2082, 0x02, "MQ Map Chest", RHT_SHADOW_TEMPLE_MQ_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30417, 0x0F, "MQ Beamos Silver Rupees Chest", RHT_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x04, "MQ Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "MQ Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x06, "MQ Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "MQ Invisible Spikes Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "MQ Boss Key Chest", RHT_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, { Category::cVanillaBossKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "MQ Spike Walls Left Chest", RHT_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31184, 0x10, "MQ Stalfos Room Chest", RHT_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26710, 0x16, "MQ Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "MQ Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31053, 0x0D, "MQ Bomb Flower Chest", RHT_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26709, 0x15, "MQ Wind Hint Chest", RHT_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26932, 0x14, "MQ After Wind Hidden Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RG_ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "MQ After Wind Enemy Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26702, 0x0E, "MQ Near Ship Invisible Chest", RHT_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_SHADOW_TEMPLE, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 1553, 0x06, "MQ Freestanding Key", RHT_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 6145, 0x01, "MQ Compass Chest", RHT_SHADOW_TEMPLE_MQ_COMPASS_CHEST, RG_SHADOW_TEMPLE_COMPASS, true); + locationTable[RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 5607, 0x07, "MQ Hover Boots Chest", RHT_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, RG_HOVER_BOOTS, true); + locationTable[RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30787, 0x03, "MQ Early Gibdos Chest", RHT_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_MAP_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 2082, 0x02, "MQ Map Chest", RHT_SHADOW_TEMPLE_MQ_MAP_CHEST, RG_SHADOW_TEMPLE_MAP, true); + locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30417, 0x0F, "MQ Beamos Silver Rupees Chest", RHT_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, RG_ARROWS_5); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22662, 0x04, "MQ Falling Spikes Switch Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22853, 0x05, "MQ Falling Spikes Lower Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, RG_ARROWS_10); + locationTable[RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, -30652, 0x06, "MQ Falling Spikes Upper Chest", RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, RG_ARROWS_5); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30857, 0x09, "MQ Invisible Spikes Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RCQUEST_MQ, RCTYPE_BOSS_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 10219, 0x0B, "MQ Boss Key Chest", RHT_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, RG_SHADOW_TEMPLE_BOSS_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22666, 0x0A, "MQ Spike Walls Left Chest", RHT_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31184, 0x10, "MQ Stalfos Room Chest", RHT_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RG_RED_RUPEE); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26710, 0x16, "MQ Invisible Blades Invisible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 22668, 0x0C, "MQ Invisible Blades Visible Chest", RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 31053, 0x0D, "MQ Bomb Flower Chest", RHT_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, RG_ARROWS_10); + locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26709, 0x15, "MQ Wind Hint Chest", RHT_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26932, 0x14, "MQ After Wind Hidden Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, RG_ARROWS_5); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 30856, 0x08, "MQ After Wind Enemy Chest", RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, RG_BLUE_RUPEE); + locationTable[RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = Location::Chest(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_SHADOW_TEMPLE, 26702, 0x0E, "MQ Near Ship Invisible Chest", RHT_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, RG_SHADOW_TEMPLE_SMALL_KEY, true); + locationTable[RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, 1553, 0x06, "MQ Freestanding Key", RHT_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, true); // Bottom of the Well Vanilla - locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22600, 0x08, "Front Left Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20578, 0x02, "Front Center Bombable Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22597, 0x05, "Right Bottom Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2049, 0x01, "Compass Chest", RHT_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20558, 0x0E, "Center Skulltula Chest", RHT_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RG_DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23684, 0x04, "Back Left Bombable Chest", RHT_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RG_DEKU_NUTS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 4419, 0x03, "Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 27348, 0x14, "Invisible Chest", RHT_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23760, 0x10, "Underwater Front Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RG_BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22793, 0x09, "Underwater Left Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2087, 0x07, "Map Chest", RHT_BOTTOM_OF_THE_WELL_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21802, 0x0A, "Fire Keese Chest", RHT_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RG_DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21836, 0x0C, "Like Like Chest", RHT_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RG_HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "Freestanding Key", RHT_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22600, 0x08, "Front Left Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20578, 0x02, "Front Center Bombable Chest", RHT_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, RG_BOMBCHU_10); + locationTable[RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22597, 0x05, "Right Bottom Fake Wall Chest", RHT_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, true); + locationTable[RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2049, 0x01, "Compass Chest", RHT_BOTTOM_OF_THE_WELL_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, true); + locationTable[RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 20558, 0x0E, "Center Skulltula Chest", RHT_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, RG_DEKU_NUTS_5); + locationTable[RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23684, 0x04, "Back Left Bombable Chest", RHT_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, RG_DEKU_NUTS_10); + locationTable[RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 4419, 0x03, "Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, true); + locationTable[RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 27348, 0x14, "Invisible Chest", RHT_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, RG_HUGE_RUPEE); + locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 23760, 0x10, "Underwater Front Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, RG_BOMBS_10); + locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 22793, 0x09, "Underwater Left Chest", RHT_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_BOTTOM_OF_THE_WELL_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2087, 0x07, "Map Chest", RHT_BOTTOM_OF_THE_WELL_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, true); + locationTable[RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21802, 0x0A, "Fire Keese Chest", RHT_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, RG_DEKU_SHIELD); + locationTable[RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 21836, 0x0C, "Like Like Chest", RHT_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, RG_HYLIAN_SHIELD); + locationTable[RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "Freestanding Key", RHT_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, true); // Bottom of the Well Master Quest - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2083, 0x03, "MQ Map Chest", RHT_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, -20159, 0x01, "MQ Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 6146, 0x02, "MQ Compass Chest", RHT_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 529, 0x02, "MQ Dead Hand Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_BOTTOM_OF_THE_WELL, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "MQ East Inner Room Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 2083, 0x03, "MQ Map Chest", RHT_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, RG_BOTTOM_OF_THE_WELL_MAP, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, -20159, 0x01, "MQ Lens of Truth Chest", RHT_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, RG_LENS_OF_TRUTH, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = Location::Chest(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_BOTTOM_OF_THE_WELL, 6146, 0x02, "MQ Compass Chest", RHT_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, RG_BOTTOM_OF_THE_WELL_COMPASS, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 529, 0x02, "MQ Dead Hand Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, true); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, 273, 0x01, "MQ East Inner Room Freestanding Key", RHT_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, true); // Ice Cavern Vanilla - locationTable[RC_ICE_CAVERN_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2080, 0x00, "Map Chest", RHT_ICE_CAVERN_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2049, 0x01, "Compass Chest", RHT_ICE_CAVERN_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_IRON_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "Iron Boots Chest", RHT_ICE_CAVERN_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_FREESTANDING_POH, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "Freestanding PoH", RHT_ICE_CAVERN_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2080, 0x00, "Map Chest", RHT_ICE_CAVERN_MAP_CHEST, RG_ICE_CAVERN_MAP, true); + locationTable[RC_ICE_CAVERN_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2049, 0x01, "Compass Chest", RHT_ICE_CAVERN_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, true); + locationTable[RC_ICE_CAVERN_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_IRON_BOOTS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "Iron Boots Chest", RHT_ICE_CAVERN_IRON_BOOTS_CHEST, RG_IRON_BOOTS, true); + locationTable[RC_ICE_CAVERN_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_FREESTANDING_POH, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "Freestanding PoH", RHT_ICE_CAVERN_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Ice Cavern Master Quest - locationTable[RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "MQ Iron Boots Chest", RHT_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RG_IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2048, 0x00, "MQ Compass Chest", RHT_ICE_CAVERN_MQ_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, { Category::cVanillaCompass }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP_COMPASS, RCAREA_ICE_CAVERN, ACTOR_EN_BOX, SCENE_ICE_CAVERN, -18399, 0x01, "MQ Map Chest", RHT_ICE_CAVERN_MQ_MAP_CHEST, RG_ICE_CAVERN_MAP, { Category::cVanillaMap }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_ICE_CAVERN_MQ_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_ICE_CAVERN, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "MQ Freestanding PoH", RHT_ICE_CAVERN_MQ_FREESTANDING_POH, RG_PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); + locationTable[RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 5570, 0x02, "MQ Iron Boots Chest", RHT_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, RG_IRON_BOOTS, true); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_COMPASS_CHEST, RCQUEST_MQ, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_ICE_CAVERN, 2048, 0x00, "MQ Compass Chest", RHT_ICE_CAVERN_MQ_COMPASS_CHEST, RG_ICE_CAVERN_COMPASS, true); + locationTable[RC_ICE_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_ICE_CAVERN, -18399, 0x01, "MQ Map Chest", RHT_ICE_CAVERN_MQ_MAP_CHEST, RG_ICE_CAVERN_MAP, true); + locationTable[RC_ICE_CAVERN_MQ_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "MQ Freestanding PoH", RHT_ICE_CAVERN_MQ_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Gerudo Training Grounds Vanilla - locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, 0x13, "Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, 0x07, "Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23206, 0x06, "Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22889, 0x09, "Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 2860, 0x0C, "Maze Path Final Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23877, 0x05, "Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22888, 0x08, "Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "Hammer Room Clear Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31089, 0x11, "Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31439, 0x0F, "Heavy Block First Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RG_HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 30862, 0x0E, "Heavy Block Second Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24450, 0x02, "Heavy Block Fourth Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); + locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, 0x13, "Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, 0x07, "Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RG_ARROWS_10); + locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23206, 0x06, "Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22889, 0x09, "Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RG_ARROWS_30); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 2860, 0x0C, "Maze Path Final Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RG_ICE_ARROWS, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23877, 0x05, "Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RG_BOMBCHU_5); + locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22888, 0x08, "Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RG_ARROWS_30); + locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "Hammer Room Clear Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RG_ARROWS_10); + locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31089, 0x11, "Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_30); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31439, 0x0F, "Heavy Block First Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RG_HUGE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 30862, 0x0E, "Heavy Block Second Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24450, 0x02, "Heavy Block Fourth Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RG_ICE_TRAP); + locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); // Gerudo Training Grounds Master Quest - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23879, 0x07, "MQ Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RG_BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22867, 0x13, "MQ Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30304, 0x00, "MQ First Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31057, 0x11, "MQ Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -32669, 0x03, "MQ Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "MQ Second Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -17628, 0x04, "MQ Ice Arrows Chest", RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RG_ICE_ARROWS, { Category::cSongDungeonReward }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22661, 0x05, "MQ Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22918, 0x06, "MQ Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RG_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24136, 0x08, "MQ Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24137, 0x09, "MQ Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "MQ Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23211, 0x0B, "MQ Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "MQ Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND, true); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GERUDO_TRAINING_GROUND, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31394, 0x02, "MQ Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RG_PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23879, 0x07, "MQ Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RG_BOMBCHU_5); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22867, 0x13, "MQ Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RG_ARROWS_10); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30304, 0x00, "MQ First Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31057, 0x11, "MQ Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_10); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -32669, 0x03, "MQ Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RG_BOMBCHU_10); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "MQ Second Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RG_ARROWS_10); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -17628, 0x04, "MQ Ice Arrows Chest", RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RG_ICE_ARROWS, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22661, 0x05, "MQ Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22918, 0x06, "MQ Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RG_GREEN_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24136, 0x08, "MQ Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24137, 0x09, "MQ Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, RG_TREASURE_GAME_GREEN_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "MQ Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23211, 0x0B, "MQ Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, RG_PURPLE_RUPEE); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "MQ Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RG_TREASURE_GAME_GREEN_RUPEE, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31394, 0x02, "MQ Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, RG_PURPLE_RUPEE); // Ganon's Castle Shared - locationTable[RC_GANONS_TOWER_BOSS_KEY_CHEST] = Location::Chest(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCQUEST_BOTH, RCTYPE_GANON_BOSS_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_GANONS_TOWER, 10219, 0x0B, "Tower Boss Key Chest", RHT_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_GANONS_TOWER_BOSS_KEY_CHEST] = Location::Chest(RC_GANONS_TOWER_BOSS_KEY_CHEST, RCQUEST_BOTH, RCTYPE_GANON_BOSS_KEY, ACTOR_EN_BOX, SCENE_GANONS_TOWER, 10219, 0x0B, "Tower Boss Key Chest", RHT_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY, true); // Ganon's Castle Vanilla - locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30857, 0x09, "Forest Trial Chest", RHT_GANONS_CASTLE_FOREST_TRIAL_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24455, 0x07, "Water Trial Left Chest", RHT_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22790, 0x06, "Water Trial Right Chest", RHT_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22664, 0x08, "Shadow Trial Front Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 14021, 0x05, "Shadow Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -29326, 0x12, "Spirit Trial Crystal Switch Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RG_BOMBCHU_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22668, 0x0C, "Light Trial First Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RG_BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24459, 0x0B, "Light Trial Second Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22797, 0x0D, "Light Trial Third Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24462, 0x0E, "Light Trial First Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22890, 0x0A, "Light Trial Second Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RG_ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30857, 0x09, "Forest Trial Chest", RHT_GANONS_CASTLE_FOREST_TRIAL_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24455, 0x07, "Water Trial Left Chest", RHT_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, RG_ICE_TRAP); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22790, 0x06, "Water Trial Right Chest", RHT_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22664, 0x08, "Shadow Trial Front Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 14021, 0x05, "Shadow Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, true); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -29326, 0x12, "Spirit Trial Crystal Switch Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, RG_BOMBCHU_20); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22668, 0x0C, "Light Trial First Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, RG_BLUE_RUPEE); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24459, 0x0B, "Light Trial Second Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, RG_ICE_TRAP); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22797, 0x0D, "Light Trial Third Left Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24462, 0x0E, "Light Trial First Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, RG_ICE_TRAP); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22890, 0x0A, "Light Trial Second Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, RG_ARROWS_30); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT)); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT)); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT)); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT)); // Ganon's Castle MQ - locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -32733, 0x03, "MQ Forest Trial Frozen Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RG_BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30460, 0x04, "MQ Light Trial Lullaby Chest", RHT_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30400, 0x00, "MQ Shadow Trial Bomb Flower Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30651, 0x05, "MQ Shadow Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -18746, 0x06, "MQ Spirit Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30457, 0x07, "MQ Spirit Trial Sun Back Right Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30648, 0x08, "MQ Spirit Trial Sun Back Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30455, 0x09, "MQ Spirit Trial Sun Front Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RG_RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, RCAREA_GANONS_CASTLE, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, RCAREA_GANONS_CASTLE, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, { Category::cVanillaSmallKey }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, 0x30, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, 0x37, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, 0x33, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, 0x39, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_30, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, RCAREA_GANONS_CASTLE, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, 0x3A, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, { Category::cDekuScrub }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -32733, 0x03, "MQ Forest Trial Frozen Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, RG_BOMBS_5); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30460, 0x04, "MQ Light Trial Lullaby Chest", RHT_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RG_RECOVERY_HEART); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30400, 0x00, "MQ Shadow Trial Bomb Flower Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, RG_ARROWS_10); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30651, 0x05, "MQ Shadow Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -18746, 0x06, "MQ Spirit Trial Golden Gauntlets Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, RG_PROGRESSIVE_STRENGTH, true); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30457, 0x07, "MQ Spirit Trial Sun Back Right Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30648, 0x08, "MQ Spirit Trial Sun Back Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, RG_GANONS_CASTLE_SMALL_KEY); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30455, 0x09, "MQ Spirit Trial Sun Front Left Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RG_RECOVERY_HEART); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, true); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT)); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT)); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER)); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT)); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT)); // Gold Skulltula Tokens // Dungeons // Deku Tree - locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Compass Room", RHT_DEKU_TREE_MQ_GS_COMPASS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, RCAREA_DEKU_TREE, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); + locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM); + locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE); + locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES); + locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM); + locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY); + locationTable[RC_DEKU_TREE_MQ_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Compass Room", RHT_DEKU_TREE_MQ_GS_COMPASS_ROOM); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM); // Dodongo's Cavern - locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); + locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS); + locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW); + locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS); + locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM); + locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER); + locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS); + locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS); + locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM); + locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY); + locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT); + locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY); + locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM); + locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL); // Fire Temple - locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); + locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM); + locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP); + locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB); + locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER); + locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM); + locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE); // Water Temple - locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", RHT_WATER_TEMPLE_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); + locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE); + locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM); + locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR); + locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST); + locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", RHT_WATER_TEMPLE_GS_RIVER); + locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH); + locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA); + locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY); + locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER); + locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH); // Spirit Temple - locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); + locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY); + locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM); // Shadow Temple - locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); + locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT); + locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM); + locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT); + locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM); + locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS); // Bottom of the Well - locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM); // Ice Cavern - locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE, { Category::cSkulltula }, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); + locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM); + locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM); + locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM); + locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW); + locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK); + locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE); // Overworld // Kokiri Forest - locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", RHT_KF_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, { Category::cSkulltula }, 0x0C, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", RHT_KF_GS_BEAN_PATCH, 0x0C); + locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, 0x0C); + locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, 0x0C); // Lost Woods - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", RHT_LW_GS_ABOVE_THEATER, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", RHT_SFM_GS, { Category::cSkulltula }, 0x0D, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, 0x0D); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, 0x0D); + locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", RHT_LW_GS_ABOVE_THEATER, 0x0D); + locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", RHT_SFM_GS, 0x0D); // Hyrule Field - locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", RHT_HF_GS_COW_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, { Category::cSkulltula }, 0x0A, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); + locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", RHT_HF_GS_COW_GROTTO, 0x0A); + locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, 0x0A); // Lake Hylia - locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", RHT_LH_GS_BEAN_PATCH, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", RHT_LH_GS_SMALL_ISLAND, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", RHT_LH_GS_LAB_WALL, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", RHT_LH_GS_LAB_CRATE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", RHT_LH_GS_TREE, { Category::cSkulltula }, 0x12, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", RHT_LH_GS_BEAN_PATCH, 0x12); + locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", RHT_LH_GS_SMALL_ISLAND, 0x12); + locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", RHT_LH_GS_LAB_WALL, 0x12); + locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", RHT_LH_GS_LAB_CRATE, 0x12); + locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", RHT_LH_GS_TREE, 0x12); // Gerudo Valley - locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", RHT_GV_GS_BEAN_PATCH, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", RHT_GV_GS_PILLAR, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", RHT_GV_GS_BEHIND_TENT, { Category::cSkulltula }, 0x13, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", RHT_GV_GS_BEAN_PATCH, 0x13); + locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, 0x13); + locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", RHT_GV_GS_PILLAR, 0x13); + locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", RHT_GV_GS_BEHIND_TENT, 0x13); // Gerudo Fortress - locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", RHT_GF_GS_TOP_FLOOR, { Category::cSkulltula }, 0x14, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, 0x14); + locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", RHT_GF_GS_TOP_FLOOR, 0x14); // Wasteland & Desert Colossus - locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", RHT_WASTELAND_GS, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", RHT_COLOSSUS_GS_HILL, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", RHT_COLOSSUS_GS_TREE, { Category::cSkulltula }, 0x15, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", RHT_WASTELAND_GS, 0x15); + locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, 0x15); + locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", RHT_COLOSSUS_GS_HILL, 0x15); + locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", RHT_COLOSSUS_GS_TREE, 0x15); // Hyrule Castle, Market, and Outside Ganon's Castle - locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, 11777, 0x01, "OGC GS", RHT_OGC_GS, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", RHT_HC_GS_TREE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, { Category::cSkulltula }, 0x0E, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, SCENE_OUTSIDE_GANONS_CASTLE, 11777, 0x01, "OGC GS", RHT_OGC_GS, 0x0E); + locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, 0x0E); + locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", RHT_HC_GS_TREE, 0x0E); + locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, 0x0E); // Kakariko - locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", RHT_KAK_GS_TREE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", RHT_KAK_GS_WATCHTOWER, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, 0x10); + locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, 0x10); + locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, 0x10); + locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", RHT_KAK_GS_TREE, 0x10); + locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", RHT_KAK_GS_WATCHTOWER, 0x10); + locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, 0x10); // Graveyard - locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", RHT_GRAVEYARD_GS_WALL, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, { Category::cSkulltula }, 0x10, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", RHT_GRAVEYARD_GS_WALL, 0x10); + locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, 0x10); // Death Mountain - locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 28417, 0x01, "GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, -28800, 0x80, "GS Crate", RHT_DMC_GS_CRATE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", RHT_DMT_GS_NEAR_KAK, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, { Category::cSkulltula }, 0x0F, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 28417, 0x01, "GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, 0x0F); + locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, -28800, 0x80, "GS Crate", RHT_DMC_GS_CRATE, 0x0F); + locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, 0x0F); + locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", RHT_DMT_GS_NEAR_KAK, 0x0F); + locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, 0x0F); + locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, 0x0F); + locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, 0x0F); + locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, 0x0F); // Zora's River, Domain, and Fountain - locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", RHT_ZR_GS_LADDER, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", RHT_ZR_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", RHT_ZF_GS_TREE, { Category::cSkulltula }, 0x11, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", RHT_ZR_GS_LADDER, 0x11); + locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", RHT_ZR_GS_TREE, 0x11); + locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, 0x11); + locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, 0x11); + locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, 0x11); + locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, 0x11); + locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, 0x11); + locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", RHT_ZF_GS_TREE, 0x11); // Lon Lon Ranch - locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", RHT_LLR_GS_BACK_WALL, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", RHT_LLR_GS_RAIN_SHED, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", RHT_LLR_GS_HOUSE_WINDOW, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", RHT_LLR_GS_TREE, { Category::cSkulltula }, 0x0B, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); + locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", RHT_LLR_GS_BACK_WALL, 0x0B); + locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", RHT_LLR_GS_RAIN_SHED, 0x0B); + locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", RHT_LLR_GS_HOUSE_WINDOW, 0x0B); + locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", RHT_LLR_GS_TREE, 0x0B); // Bosses - locationTable[RC_LINKS_POCKET] = Location::Reward(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, true); - locationTable[RC_QUEEN_GOHMA] = Location::Reward(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DEKU_TREE, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, DungeonId::DUNGEON_DEKU_TREE, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_KING_DODONGO] = Location::Reward(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, DungeonId::DUNGEON_DODONGOS_CAVERN, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_BARINADE] = Location::Reward(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, DungeonId::DUNGEON_JABUJABUS_BELLY, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_PHANTOM_GANON] = Location::Reward(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FOREST_TEMPLE, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_VOLVAGIA] = Location::Reward(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_FIRE_TEMPLE, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_MORPHA] = Location::Reward(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_WATER_TEMPLE, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_WATER_TEMPLE, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_TWINROVA] = Location::Reward(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SPIRIT_TEMPLE, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_BONGO_BONGO] = Location::Reward(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, DungeonId::DUNGEON_SHADOW_TEMPLE, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); - locationTable[RC_GANON] = Location::Reward(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_GANONS_CASTLE, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, DungeonId::DUNGEON_GANONS_CASTLE_CRUMBLING, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[RC_GIFT_FROM_SAGES] = Location::Reward(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, {}, SpoilerCollectionCheck::EventChkInf(0xC9), SpoilerCollectionCheckGroup::GROUP_NO_GROUP, true); + locationTable[RC_LINKS_POCKET] = Location::Base(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), true); + locationTable[RC_QUEEN_GOHMA] = Location::Base(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP), true); + locationTable[RC_KING_DODONGO] = Location::Base(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), true); + locationTable[RC_BARINADE] = Location::Base(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP), true); + locationTable[RC_PHANTOM_GANON] = Location::Base(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), true); + locationTable[RC_VOLVAGIA] = Location::Base(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), true); + locationTable[RC_MORPHA] = Location::Base(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), true); + locationTable[RC_TWINROVA] = Location::Base(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), true); + locationTable[RC_BONGO_BONGO] = Location::Base(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), true); + locationTable[RC_GANON] = Location::Base(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE); + locationTable[RC_GIFT_FROM_SAGES] = Location::Base(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, SpoilerCollectionCheck::EventChkInf(0xC9), true); // Heart Containers - locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DEKU_TREE, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, 0x4F, "Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE, true); - locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_DODONGOS_CAVERN, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, 0x4F, "King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN, true); - locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_JABU_JABUS_BELLY, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, 0x4F, "Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY, true); - locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FOREST_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, 0x4F, "Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE, true); - locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_FIRE_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, 0x4F, "Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE, true); - locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_WATER_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, 0x4F, "Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE, true); - locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SPIRIT_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, 0x4F, "Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE, true); - locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, RCAREA_SHADOW_TEMPLE, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, 0x4F, "Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, { Category::cSongDungeonReward }, SpoilerCollectionCheck::Collectable(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE, true); + locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x11, 0x1F), true); + locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x12, 0x1F), true); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, "Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x13, 0x1F), true); + locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x14, 0x1F), true); + locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x15, 0x1F), true); + locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x16, 0x1F), true); + locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x17, 0x1F), true); + locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x18, 0x1F), true); // Cutscenes - locationTable[RC_TOT_MASTER_SWORD] = Location::Delayed(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, {}, SpoilerCollectionCheck::EventChkInf(0x45), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x01, "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, {}, SpoilerCollectionCheck::EventChkInf(0xC4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Delayed(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, 0x02, "Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Delayed(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, 0x10, "Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, true); - locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, 0x11, "Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, 0x12, "Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, 0x13, "Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, 0x14, "Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Delayed(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, 0x15, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_GREAT_FAIRY_REWARD), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE, true); + locationTable[RC_TOT_MASTER_SWORD] = Location::Base(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, SpoilerCollectionCheck::EventChkInf(0x45), true); + locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Base(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, SpoilerCollectionCheck::EventChkInf(0xC4), true); + locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Base(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0xC1), true); + locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Base(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, "Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_GREAT_FAIRY_REWARD), true); + locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Base(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, "Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GREAT_FAIRY_REWARD), true); + locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Base(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, "Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD), true); + locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Base(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, "Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GREAT_FAIRY_REWARD), true); + locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Base(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, "Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GREAT_FAIRY_REWARD), true); + locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Base(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_GREAT_FAIRY_REWARD), true); // Songs - locationTable[RC_SHEIK_IN_FOREST] = Location::Delayed(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x20, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x50), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_SHEIK_IN_CRATER] = Location::Delayed(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x21, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x51), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, true); - locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Delayed(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_ICE_CAVERN, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, 0x22, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x52), SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN, true); - locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Delayed(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_DESERT_COLOSSUS, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, 0x23, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAC), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, true); - locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Delayed(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x24, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xAA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_SHEIK_AT_TEMPLE] = Location::Delayed(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x25, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x55), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_SONG_FROM_IMPA] = Location::Delayed(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x26, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, { Category::cSong, Category::cSongDungeonReward }, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE, true); - locationTable[RC_SONG_FROM_MALON] = Location::Delayed(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_LON_LON_RANCH, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x27, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, { Category::cSong }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, true); - locationTable[RC_SONG_FROM_SARIA] = Location::Delayed(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_SACRED_FOREST_MEADOW, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, 0x28, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, true); - locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x29, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); - locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0xA9), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); - locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + locationTable[RC_SHEIK_IN_FOREST] = Location::Base(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, SpoilerCollectionCheck::EventChkInf(0x50), true); + locationTable[RC_SHEIK_IN_CRATER] = Location::Base(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_CRATER, 0x00, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, SpoilerCollectionCheck::EventChkInf(0x51), true); + locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Base(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, SpoilerCollectionCheck::EventChkInf(0x52), true); + locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Base(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, SpoilerCollectionCheck::EventChkInf(0xAC), true); + locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Base(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, SpoilerCollectionCheck::EventChkInf(0xAA), true); + locationTable[RC_SHEIK_AT_TEMPLE] = Location::Base(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, SpoilerCollectionCheck::EventChkInf(0x55), true); + locationTable[RC_SONG_FROM_IMPA] = Location::Base(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, SpoilerCollectionCheck::EventChkInf(0x59), true); + locationTable[RC_SONG_FROM_MALON] = Location::Base(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_LON_LON_RANCH, 0x00, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), true); + locationTable[RC_SONG_FROM_SARIA] = Location::Base(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, SpoilerCollectionCheck::EventChkInf(0x57), true); + locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Base(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ROYAL_FAMILYS_TOMB, 0x00, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG), true); + locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Base(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, SpoilerCollectionCheck::EventChkInf(0xA9), true); + locationTable[RC_SONG_FROM_WINDMILL] = Location::Base(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0x00, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), true); //Beehives - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), 0x00, "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), 0x00, "Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), 0x00, "Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), 0x00, "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), 0x00, "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), 0x00, "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), 0x00, "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), 0x00, "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), 0x00, "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), 0x00, "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), 0x00, "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), 0x00, "Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), 0x00, "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), 0x00, "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), 0x00, "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), 0x00, "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), 0x00, "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), 0x00, "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), 0x00, "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), 0x00, "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), 0x00, "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), 0x00, "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), 0x00, "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), 0x00, "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), 0x00, "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), 0x00, "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), 0x00, "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), 0x00, "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), 0x00, "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), 0x00, "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), 0x00, "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, { Category::cBeehive }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT)); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), "Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), "Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT)); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO)); + locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT)); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT)); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT)); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT)); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT)); + locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), "Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO)); + locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO)); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT)); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT)); + locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO)); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT)); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT)); + locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO)); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT)); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT)); + locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO)); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT)); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT)); + locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO)); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT)); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT)); + locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA)); + locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO)); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO)); + locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO)); // Cows - locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KOKIRI_FOREST, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, 0x15, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), 0x16, "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), 0x16, "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), 0x15, "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), 0x15, "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_LON_LON_RANCH, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), 0x16, "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, 0x15, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), 0x15, "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_GERUDO_VALLEY, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, 0x15, "Cow", RHT_GV_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, 0x15, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); + locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); + locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)); + locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW)); + locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW)); + locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW)); + locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW)); + locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW)); + locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW)); + locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW)); /*------------------------------- --- SHOPS --- @@ -1385,191 +886,190 @@ void Rando::StaticData::InitLocationTable() { // 7 5 1 3 -------------------------------*/ // Kokiri Forest - locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, 0x00, "Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, 0x01, "Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 1), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, 0x02, "Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 2), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, 0x03, "Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 3), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, 0x04, "Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 4), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, 0x05, "Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 5), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, 0x06, "Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 6), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KOKIRI_FOREST, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, 0x07, "Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2D, 7), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); + locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, "Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD); + locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, "Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5); + locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, "Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10); + locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, "Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1); + locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, "Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30); + locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, "Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10); + locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, "Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30); + locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, "Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART); // Kakariko Village - locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, 0x30, "Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, 0x31, "Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, 0x32, "Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, 0x33, "Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, 0x34, "Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, 0x35, "Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, 0x36, "Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, 0x37, "Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, 0x38, "Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, 0x39, "Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, 0x3A, "Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, 0x3B, "Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, 0x3C, "Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, 0x3D, "Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, 0x3E, "Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, 0x3F, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x33, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, "Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION); + locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, "Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE); + locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, "Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30); + locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, "Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT); + locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, "Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); + locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, "Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG); + locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, "Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE); + locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, "Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH); + locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, "Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD); + locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, "Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535); + locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, "Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5); + locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, "Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART); + locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, "Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10); + locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, "Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50); + locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, "Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1); + locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30); // Market - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, 0x30, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, 0x31, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, 0x32, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, 0x33, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHUS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, 0x34, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, 0x35, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, 0x36, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, 0x37, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHUS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x32, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, 0x30, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, 0x31, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, 0x32, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, 0x33, "Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, 0x34, "Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, 0x35, "Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, 0x36, "Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, 0x37, "Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x31, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, 0x30, "Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, 0x31, "Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, 0x32, "Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 2), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, 0x33, "Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 3), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, 0x34, "Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 4), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, 0x35, "Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, 0x36, "Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 6), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, 0x37, "Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2C, 7), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHUS_10); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHUS_10); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHUS_10); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHUS_10); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHUS_20); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHUS_20); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHUS_20); + locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHUS_20); + locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION); + locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30); + locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, "Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT); + locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, "Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); + locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, "Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG); + locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, "Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE); + locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, "Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH); + locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, "Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD); + locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, "Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535); + locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, "Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5); + locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, "Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART); + locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, "Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10); + locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, "Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50); + locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, "Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1); + locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, "Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30); // Zora's Domain - locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, 0x30, "Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, 0x31, "Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 1), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, 0x32, "Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 2), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, 0x33, "Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 3), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, 0x34, "Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 4), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, 0x35, "Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 5), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, 0x36, "Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 6), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_ZORAS_DOMAIN, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, 0x37, "Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2F, 7), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); + locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, "Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC); + locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, "Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10); + locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, "Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART); + locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, "Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30); + locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, "Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); + locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, "Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50); + locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, "Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH); + locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, "Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50); // Goron City - locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, 0x30, "Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 0), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, 0x31, "Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 1), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, 0x32, "Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 2), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, 0x33, "Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 3), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, 0x34, "Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 4), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, 0x35, "Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 5), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, 0x36, "Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 6), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_GORON_CITY, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, 0x37, "Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART, { Category::cShop }, SpoilerCollectionCheck::ShopItem(0x2E, 7), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); + locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, "Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525); + locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, "Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10); + locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, "Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20); + locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, "Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30); + locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, "Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC); + locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, "Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART); + locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, "Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40); + locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, "Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART); /* +--------------+ | FISHSANITY | +--------------+ */ // Fishing Pond - locationTable[RC_LH_CHILD_FISH_1] = Location::Base(RC_LH_CHILD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Child Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_2] = Location::Base(RC_LH_CHILD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Child Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_3] = Location::Base(RC_LH_CHILD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Child Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_4] = Location::Base(RC_LH_CHILD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Child Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_5] = Location::Base(RC_LH_CHILD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Child Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_6] = Location::Base(RC_LH_CHILD_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Child Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_7] = Location::Base(RC_LH_CHILD_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Child Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_8] = Location::Base(RC_LH_CHILD_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Child Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_9] = Location::Base(RC_LH_CHILD_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Child Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_10] = Location::Base(RC_LH_CHILD_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Child Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_11] = Location::Base(RC_LH_CHILD_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Child Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_12] = Location::Base(RC_LH_CHILD_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Child Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_13] = Location::Base(RC_LH_CHILD_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Child Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_14] = Location::Base(RC_LH_CHILD_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Child Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_FISH_15] = Location::Base(RC_LH_CHILD_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Child Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_LOACH_1] = Location::Base(RC_LH_CHILD_LOACH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Child Pond Loach 1", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_CHILD_LOACH_2] = Location::Base(RC_LH_CHILD_LOACH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 116, 0x00, "Child Pond Loach 2", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_1] = Location::Base(RC_LH_ADULT_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 100, 0x00, "Adult Pond Fish 1", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_2] = Location::Base(RC_LH_ADULT_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 101, 0x00, "Adult Pond Fish 2", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_3] = Location::Base(RC_LH_ADULT_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 102, 0x00, "Adult Pond Fish 3", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_4] = Location::Base(RC_LH_ADULT_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 103, 0x00, "Adult Pond Fish 4", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_5] = Location::Base(RC_LH_ADULT_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 104, 0x00, "Adult Pond Fish 5", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_6] = Location::Base(RC_LH_ADULT_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 105, 0x00, "Adult Pond Fish 6", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_7] = Location::Base(RC_LH_ADULT_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 106, 0x00, "Adult Pond Fish 7", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_8] = Location::Base(RC_LH_ADULT_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 107, 0x00, "Adult Pond Fish 8", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_9] = Location::Base(RC_LH_ADULT_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 108, 0x00, "Adult Pond Fish 9", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_10] = Location::Base(RC_LH_ADULT_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 109, 0x00, "Adult Pond Fish 10", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_11] = Location::Base(RC_LH_ADULT_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 110, 0x00, "Adult Pond Fish 11", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_12] = Location::Base(RC_LH_ADULT_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 111, 0x00, "Adult Pond Fish 12", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_13] = Location::Base(RC_LH_ADULT_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 112, 0x00, "Adult Pond Fish 13", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_14] = Location::Base(RC_LH_ADULT_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 113, 0x00, "Adult Pond Fish 14", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_FISH_15] = Location::Base(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 114, 0x00, "Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[RC_LH_ADULT_LOACH] = Location::Base(RC_LH_ADULT_LOACH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, 115, 0x00, "Adult Pond Loach", RHT_LH_HYRULE_LOACH, RG_NONE, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); + locationTable[RC_LH_CHILD_FISH_1] = Location::Fish(RC_LH_CHILD_FISH_1, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 100, RAND_INF_CHILD_FISH_1, "Child Pond Fish 1", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_2] = Location::Fish(RC_LH_CHILD_FISH_2, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 101, RAND_INF_CHILD_FISH_2, "Child Pond Fish 2", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_3] = Location::Fish(RC_LH_CHILD_FISH_3, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 102, RAND_INF_CHILD_FISH_3, "Child Pond Fish 3", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_4] = Location::Fish(RC_LH_CHILD_FISH_4, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 103, RAND_INF_CHILD_FISH_4, "Child Pond Fish 4", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_5] = Location::Fish(RC_LH_CHILD_FISH_5, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 104, RAND_INF_CHILD_FISH_5, "Child Pond Fish 5", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_6] = Location::Fish(RC_LH_CHILD_FISH_6, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 105, RAND_INF_CHILD_FISH_6, "Child Pond Fish 6", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_7] = Location::Fish(RC_LH_CHILD_FISH_7, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 106, RAND_INF_CHILD_FISH_7, "Child Pond Fish 7", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_8] = Location::Fish(RC_LH_CHILD_FISH_8, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 107, RAND_INF_CHILD_FISH_8, "Child Pond Fish 8", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_9] = Location::Fish(RC_LH_CHILD_FISH_9, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 108, RAND_INF_CHILD_FISH_9, "Child Pond Fish 9", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_10] = Location::Fish(RC_LH_CHILD_FISH_10, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 109, RAND_INF_CHILD_FISH_10, "Child Pond Fish 10", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_11] = Location::Fish(RC_LH_CHILD_FISH_11, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 110, RAND_INF_CHILD_FISH_11, "Child Pond Fish 11", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_12] = Location::Fish(RC_LH_CHILD_FISH_12, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 111, RAND_INF_CHILD_FISH_12, "Child Pond Fish 12", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_13] = Location::Fish(RC_LH_CHILD_FISH_13, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 112, RAND_INF_CHILD_FISH_13, "Child Pond Fish 13", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_14] = Location::Fish(RC_LH_CHILD_FISH_14, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 113, RAND_INF_CHILD_FISH_14, "Child Pond Fish 14", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_15] = Location::Fish(RC_LH_CHILD_FISH_15, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 114, RAND_INF_CHILD_FISH_15, "Child Pond Fish 15", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_LOACH_1] = Location::Fish(RC_LH_CHILD_LOACH_1, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 115, RAND_INF_CHILD_LOACH_1, "Child Pond Loach 1", RHT_LH_HYRULE_LOACH, RG_NONE); + locationTable[RC_LH_CHILD_LOACH_2] = Location::Fish(RC_LH_CHILD_LOACH_2, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 116, RAND_INF_CHILD_LOACH_2, "Child Pond Loach 2", RHT_LH_HYRULE_LOACH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_1] = Location::Fish(RC_LH_ADULT_FISH_1, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 100, RAND_INF_ADULT_FISH_1, "Adult Pond Fish 1", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_2] = Location::Fish(RC_LH_ADULT_FISH_2, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 101, RAND_INF_ADULT_FISH_2, "Adult Pond Fish 2", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_3] = Location::Fish(RC_LH_ADULT_FISH_3, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 102, RAND_INF_ADULT_FISH_3, "Adult Pond Fish 3", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_4] = Location::Fish(RC_LH_ADULT_FISH_4, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 103, RAND_INF_ADULT_FISH_4, "Adult Pond Fish 4", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_5] = Location::Fish(RC_LH_ADULT_FISH_5, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 104, RAND_INF_ADULT_FISH_5, "Adult Pond Fish 5", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_6] = Location::Fish(RC_LH_ADULT_FISH_6, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 105, RAND_INF_ADULT_FISH_6, "Adult Pond Fish 6", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_7] = Location::Fish(RC_LH_ADULT_FISH_7, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 106, RAND_INF_ADULT_FISH_7, "Adult Pond Fish 7", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_8] = Location::Fish(RC_LH_ADULT_FISH_8, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 107, RAND_INF_ADULT_FISH_8, "Adult Pond Fish 8", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_9] = Location::Fish(RC_LH_ADULT_FISH_9, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 108, RAND_INF_ADULT_FISH_9, "Adult Pond Fish 9", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_10] = Location::Fish(RC_LH_ADULT_FISH_10, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 109, RAND_INF_ADULT_FISH_10, "Adult Pond Fish 10", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_11] = Location::Fish(RC_LH_ADULT_FISH_11, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 110, RAND_INF_ADULT_FISH_11, "Adult Pond Fish 11", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_12] = Location::Fish(RC_LH_ADULT_FISH_12, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 111, RAND_INF_ADULT_FISH_12, "Adult Pond Fish 12", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_13] = Location::Fish(RC_LH_ADULT_FISH_13, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 112, RAND_INF_ADULT_FISH_13, "Adult Pond Fish 13", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_14] = Location::Fish(RC_LH_ADULT_FISH_14, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 113, RAND_INF_ADULT_FISH_14, "Adult Pond Fish 14", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_15] = Location::Fish(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 114, RAND_INF_ADULT_FISH_15, "Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_LOACH] = Location::Fish(RC_LH_ADULT_LOACH, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 115, RAND_INF_ADULT_LOACH, "Adult Pond Loach", RHT_LH_HYRULE_LOACH, RG_NONE); // Grotto fish - locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::Base(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KOKIRI_FOREST, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x2C, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_LOST_WOODS, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x14, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::Base(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x22, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::Base(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x03, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_HYRULE_FIELD, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x00, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::Base(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x28, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::Base(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x57, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::Base(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x7A, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::Base(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_RIVER, ACTOR_EN_FISH, SCENE_GROTTOS, 1, 0x00, "Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0x29, SCENE_GROTTOS), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); + locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, 0x12C, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::GrottoFish(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_LOST_WOODS, 0x114, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH); + locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::GrottoFish(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x122, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH); + locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x103, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH); + locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::GrottoFish(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x100, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH); + locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, 0x128, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH); + locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, 0x157, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH); + locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::GrottoFish(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, 0x17A, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH); + locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, 0x129, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH); // Zora's Domain fish - locationTable[RC_ZD_FISH_1] = Location::Base(RC_ZD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, 0x00, "Fish 1", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_2] = Location::Base(RC_ZD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, 0x00, "Fish 2", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_3] = Location::Base(RC_ZD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 2, 0x00, "Fish 3", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_4] = Location::Base(RC_ZD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, 0x00, "Fish 4", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[RC_ZD_FISH_5] = Location::Base(RC_ZD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_ZORAS_DOMAIN, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, 0x00, "Fish 5", RHT_ZD_FISH, RG_FISH, { Category::cFish }, SpoilerCollectionCheck::Fish(0xFF, SCENE_ZORAS_DOMAIN), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - + locationTable[RC_ZD_FISH_1] = Location::Fish(RC_ZD_FISH_1, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, RAND_INF_ZD_FISH_1, "Fish 1", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_2] = Location::Fish(RC_ZD_FISH_2, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, RAND_INF_ZD_FISH_2, "Fish 2", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_3] = Location::Fish(RC_ZD_FISH_3, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 2, RAND_INF_ZD_FISH_3, "Fish 3", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_4] = Location::Fish(RC_ZD_FISH_4, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, RAND_INF_ZD_FISH_4, "Fish 4", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_5] = Location::Fish(RC_ZD_FISH_5, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, RAND_INF_ZD_FISH_5, "Fish 5", RHT_ZD_FISH, RG_FISH); // Gossip Stones - locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 14341, 0x05, "Gossip Stone", {}); - locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, 0x04, "Gossip Stone", {}); - locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 14362, 0x1A, "Gossip Stone", {}); - locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, 4372, 0x14, "Gossip Stone", {}); - locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 14353, 0x11, "Gossip Stone", {}); - locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14357, 0x15, "Maze Gossip Stone", {}); - locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14873, 0x19, "Medigoron Gossip Stone", {}); - locationTable[RC_GRAVEYARD_GOSSIP_STONE] = Location::HintStone(RC_GRAVEYARD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 14346, 0x0A, "Gossip Stone", {}); - locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14610, 0x12, "Malon Gossip Stone", {}); - locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14347, 0x0B, "Rock Wall Gossip Stone", {}); - locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, 0x13, "Storms Grotto Gossip Stone", {}); - locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14623, 0x1F, "Deku Tree Left Gossip Stone", {}); - locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14880, 0x20, "Deku Tree Right Gossip Stone", {}); - locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14366, 0x1E, "Gossip Stone", {}); - locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, 0x3C, "Storms Gossip Stone", {}); - locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14339, 0x03, "Lab Gossip Stone", {}); - locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14863, 0x0F, "Southeast Gossip Stone", {}); - locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14600, 0x08, "Southwest Gossip Stone", {}); - locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 14365, 0x1D, "Gossip Stone", {}); - locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14358, 0x16, "Maze Lower Gossip Stone", {}); - locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14615, 0x17, "Maze Upper Gossip Stone", {}); - locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14876, 0x1C, "Saria Gossip Stone", {}); - locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x06, "ToT Left Gossip Stone", {}); - locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x07, "ToT Right Gossip Stone", {}); - locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x10, "ToT Right Center Gossip Stone", {}); - locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x0E, "ToT Left Center Gossip Stone", {}); - locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 14345, 0x09, "Gossip Stone", {}); - locationTable[RC_ZF_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_ZF_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x01, "Fairy Gossip Stone", {}); - locationTable[RC_ZF_JABU_GOSSIP_STONE] = Location::HintStone(RC_ZF_JABU_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x02, "Jabu Gossip Stone", {}); - locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14605, 0x0D, "Near Grottos Gossip Stone", {}); - locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14860, 0x0C, "Near Domain Gossip Stone", {}); - locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, 0x1B, "Cow Grotto Gossip Stone", {}); - locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, 0x30, "Near Market Gossip Stone", {}); - locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, 0x32, "Southeast Gossip Stone", {}); - locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, 0x33, "Open Grotto Gossip Stone", {}); - locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, 0x38, "Open Grotto Gossip Stone", {}); - locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, 0x39, "Open Grotto Gossip Stone", {}); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, 0x34, "Near Shortcuts Gossip Stone", {}); - locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, 0x37, "Storms Grotto Gossip Stone", {}); - locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, 0x3A, "Upper Grotto Gossip Stone", {}); + locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 14341, "Gossip Stone"); + locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, "Gossip Stone"); + locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 14362, "Gossip Stone"); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 4372, "Gossip Stone"); + locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 14353, "Gossip Stone"); + locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14357, "Maze Gossip Stone"); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14873, "Medigoron Gossip Stone"); + locationTable[RC_GRAVEYARD_GOSSIP_STONE] = Location::HintStone(RC_GRAVEYARD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GRAVEYARD, 14346, "Gossip Stone"); + locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14610, "Malon Gossip Stone"); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14347, "Rock Wall Gossip Stone"); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, "Storms Grotto Gossip Stone"); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14623, "Deku Tree Left Gossip Stone"); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14880, "Deku Tree Right Gossip Stone"); + locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14366, "Gossip Stone"); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, "Storms Gossip Stone"); + locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14339, "Lab Gossip Stone"); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14863, "Southeast Gossip Stone"); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14600, "Southwest Gossip Stone"); + locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LOST_WOODS, 14365, "Gossip Stone"); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14358, "Maze Lower Gossip Stone"); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14615, "Maze Upper Gossip Stone"); + locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14876, "Saria Gossip Stone"); + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Gossip Stone"); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Gossip Stone"); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Center Gossip Stone"); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Center Gossip Stone"); + locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 14345, "Gossip Stone"); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_ZF_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Fairy Gossip Stone"); + locationTable[RC_ZF_JABU_GOSSIP_STONE] = Location::HintStone(RC_ZF_JABU_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Jabu Gossip Stone"); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14605, "Near Grottos Gossip Stone"); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14860, "Near Domain Gossip Stone"); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, "Cow Grotto Gossip Stone"); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, "Near Market Gossip Stone"); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, "Southeast Gossip Stone"); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, "Open Grotto Gossip Stone"); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, "Open Grotto Gossip Stone"); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, "Open Grotto Gossip Stone"); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, "Near Shortcuts Gossip Stone"); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, "Storms Grotto Gossip Stone"); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, "Upper Grotto Gossip Stone"); // Other Hints - locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint"); - locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); - locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, RCTYPE_GOSSIP_STONE, RCAREA_GANONS_CASTLE, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); - locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint"); - locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint"); - locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); - locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint"); - locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint"); - locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint"); - locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint"); - locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint"); - - locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); + locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint"); + locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); + locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); + locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint"); + locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint"); + locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); + locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint"); + locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint"); + locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint"); + locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint"); + locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint"); + + locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE); // clang-format on // Init locationNameToEnum diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index edb17df0c88..07215307f35 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1,4 +1,5 @@ #include "logic.h" +#include "../debugger/performanceTimer.h" #include #include @@ -6,8 +7,11 @@ #include #include +#include "soh/OTRGlobals.h" #include "dungeon.h" #include "context.h" +#include "macros.h" +#include "variables.h" #include namespace Rando { @@ -27,50 +31,50 @@ namespace Rando { bool Logic::HasItem(RandomizerGet itemName) { switch (itemName) { case RG_FAIRY_OCARINA: - return ctx->CheckInventory(ITEM_OCARINA_FAIRY, false); + return CheckInventory(ITEM_OCARINA_FAIRY, false); case RG_OCARINA_OF_TIME: - return ctx->CheckInventory(ITEM_OCARINA_TIME, true); + return CheckInventory(ITEM_OCARINA_TIME, true); case RG_DINS_FIRE: - return ctx->CheckInventory(ITEM_DINS_FIRE, true); + return CheckInventory(ITEM_DINS_FIRE, true); case RG_FARORES_WIND: - return ctx->CheckInventory(ITEM_FARORES_WIND, true); + return CheckInventory(ITEM_FARORES_WIND, true); case RG_NAYRUS_LOVE: - return ctx->CheckInventory(ITEM_NAYRUS_LOVE, true); + return CheckInventory(ITEM_NAYRUS_LOVE, true); case RG_LENS_OF_TRUTH: - return ctx->CheckInventory(ITEM_LENS, true); + return CheckInventory(ITEM_LENS, true); case RG_FAIRY_BOW: - return ctx->CheckInventory(ITEM_BOW, true); + return CheckInventory(ITEM_BOW, true); case RG_MEGATON_HAMMER: - return ctx->CheckInventory(ITEM_HAMMER, true); + return CheckInventory(ITEM_HAMMER, true); case RG_HOOKSHOT: - return ctx->CheckInventory(ITEM_HOOKSHOT, false); + return CheckInventory(ITEM_HOOKSHOT, false); case RG_LONGSHOT: - return ctx->CheckInventory(ITEM_LONGSHOT, true); + return CheckInventory(ITEM_LONGSHOT, true); case RG_PROGRESSIVE_STICK_UPGRADE: case RG_STICKS: - return ctx->CurrentUpgrade(UPG_STICKS); + return CurrentUpgrade(UPG_STICKS); case RG_FIRE_ARROWS: - return ctx->CheckInventory(ITEM_ARROW_FIRE, true); + return CheckInventory(ITEM_ARROW_FIRE, true); case RG_ICE_ARROWS: - return ctx->CheckInventory(ITEM_ARROW_ICE, true); + return CheckInventory(ITEM_ARROW_ICE, true); case RG_LIGHT_ARROWS: - return ctx->CheckInventory(ITEM_ARROW_LIGHT, true); + return CheckInventory(ITEM_ARROW_LIGHT, true); case RG_PROGRESSIVE_BOMBCHUS: case RG_BOMBCHU_5: case RG_BOMBCHU_10: case RG_BOMBCHU_20: - return (BombchusEnabled && BuyBombchus) || ctx->CheckInventory(ITEM_BOMBCHU, true); + return (BombchusEnabled() && (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant)) || CheckInventory(ITEM_BOMBCHU, true); case RG_FAIRY_SLINGSHOT: - return ctx->CheckInventory(ITEM_SLINGSHOT, true); + return CheckInventory(ITEM_SLINGSHOT, true); case RG_BOOMERANG: - return ctx->CheckInventory(ITEM_BOOMERANG, true); + return CheckInventory(ITEM_BOOMERANG, true); case RG_PROGRESSIVE_NUT_UPGRADE: case RG_NUTS: - return ctx->CurrentUpgrade(UPG_NUTS); + return CurrentUpgrade(UPG_NUTS); case RG_SCARECROW: - return Scarecrow; + return ScarecrowsSong() && CanUse(RG_HOOKSHOT); case RG_DISTANT_SCARECROW: - return DistantScarecrow; + return ScarecrowsSong() && CanUse(RG_LONGSHOT); case RG_KOKIRI_SWORD: case RG_DEKU_SHIELD: case RG_GORON_TUNIC: @@ -81,18 +85,18 @@ namespace Rando { case RG_BIGGORON_SWORD: case RG_IRON_BOOTS: case RG_HOVER_BOOTS: - return ctx->CheckEquipment(Context::RandoGetToEquipFlag.at(itemName)); + return CheckEquipment(RandoGetToEquipFlag.at(itemName)); case RG_GORONS_BRACELET: - return ctx->CurrentUpgrade(UPG_STRENGTH); + return CurrentUpgrade(UPG_STRENGTH); case RG_SILVER_GAUNTLETS: - return ctx->CurrentUpgrade(UPG_STRENGTH) >= 2; + return CurrentUpgrade(UPG_STRENGTH) >= 2; case RG_GOLDEN_GAUNTLETS: - return ctx->CurrentUpgrade(UPG_STRENGTH) >= 3; + return CurrentUpgrade(UPG_STRENGTH) >= 3; case RG_PROGRESSIVE_BOMB_BAG: case RG_BOMB_BAG: - return ctx->CurrentUpgrade(UPG_BOMB_BAG); + return CurrentUpgrade(UPG_BOMB_BAG); case RG_MAGIC_SINGLE: - return ctx->GetSaveContext()->magicLevel >= 1; + return GetSaveContext()->magicLevel >= 1; // Songs case RG_ZELDAS_LULLABY: case RG_EPONAS_SONG: @@ -119,11 +123,11 @@ namespace Rando { // Misc Quest Items case RG_STONE_OF_AGONY: case RG_GERUDO_MEMBERSHIP_CARD: - return ctx->CheckQuestItem(Context::RandoGetToQuestItem.at(itemName)); + return CheckQuestItem(RandoGetToQuestItem.at(itemName)); case RG_RUTOS_LETTER: - return ctx->CheckEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); + return CheckEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); case RG_DOUBLE_DEFENSE: - return ctx->GetSaveContext()->isDoubleDefenseAcquired; + return GetSaveContext()->isDoubleDefenseAcquired; case RG_FISHING_POLE: case RG_ZELDAS_LETTER: case RG_WEIRD_EGG: @@ -145,15 +149,17 @@ namespace Rando { case RG_TWINROVA_SOUL: case RG_GANON_SOUL: case RG_SKELETON_KEY: - return ctx->CheckRandoInf(Context::RandoGetToRandInf.at(itemName)); + return CheckRandoInf(RandoGetToRandInf.at(itemName)); // Boss Keys + case RG_EPONA: + return FreedEpona; case RG_FOREST_TEMPLE_BOSS_KEY: case RG_FIRE_TEMPLE_BOSS_KEY: case RG_WATER_TEMPLE_BOSS_KEY: case RG_SPIRIT_TEMPLE_BOSS_KEY: case RG_SHADOW_TEMPLE_BOSS_KEY: case RG_GANONS_CASTLE_BOSS_KEY: - return ctx->CheckDungeonItem(DUNGEON_KEY_BOSS, Context::RandoGetToDungeonScene.at(itemName)); + return CheckDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.at(itemName)); // Maps case RG_DEKU_TREE_MAP: case RG_DODONGOS_CAVERN_MAP: @@ -165,7 +171,7 @@ namespace Rando { case RG_SHADOW_TEMPLE_MAP: case RG_BOTTOM_OF_THE_WELL_MAP: case RG_ICE_CAVERN_MAP: - return ctx->CheckDungeonItem(DUNGEON_MAP, Context::RandoGetToDungeonScene.at(itemName)); + return CheckDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.at(itemName)); // Compasses case RG_DEKU_TREE_COMPASS: case RG_DODONGOS_CAVERN_COMPASS: @@ -177,23 +183,23 @@ namespace Rando { case RG_SHADOW_TEMPLE_COMPASS: case RG_BOTTOM_OF_THE_WELL_COMPASS: case RG_ICE_CAVERN_COMPASS: - return ctx->CheckDungeonItem(DUNGEON_COMPASS, Context::RandoGetToDungeonScene.at(itemName)); + return CheckDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.at(itemName)); // Wallets case RG_CHILD_WALLET: - return ctx->CheckRandoInf(RAND_INF_HAS_WALLET); + return CheckRandoInf(RAND_INF_HAS_WALLET); case RG_ADULT_WALLET: - return ctx->CurrentUpgrade(UPG_WALLET) >= 1; + return CurrentUpgrade(UPG_WALLET) >= 1; case RG_GIANT_WALLET: - return ctx->CurrentUpgrade(UPG_WALLET) >= 2; + return CurrentUpgrade(UPG_WALLET) >= 2; case RG_TYCOON_WALLET: - return ctx->CurrentUpgrade(UPG_WALLET) >= 3; + return CurrentUpgrade(UPG_WALLET) >= 3; // Scales case RG_BRONZE_SCALE: - return ctx->CheckRandoInf(RAND_INF_CAN_SWIM); + return CheckRandoInf(RAND_INF_CAN_SWIM); case RG_SILVER_SCALE: - return ctx->CurrentUpgrade(UPG_SCALE) >= 1; + return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: - return ctx->CurrentUpgrade(UPG_SCALE) >= 2; + return CurrentUpgrade(UPG_SCALE) >= 2; case RG_POCKET_EGG: case RG_COJIRO: case RG_ODD_MUSHROOM: @@ -204,7 +210,7 @@ namespace Rando { case RG_EYEBALL_FROG: case RG_EYEDROPS: case RG_CLAIM_CHECK: - return ctx->HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId); + return HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId); case RG_BOTTLE_WITH_BIG_POE: case RG_BOTTLE_WITH_BLUE_FIRE: case RG_BOTTLE_WITH_BLUE_POTION: @@ -216,7 +222,7 @@ namespace Rando { case RG_BOTTLE_WITH_POE: case RG_BOTTLE_WITH_RED_POTION: case RG_EMPTY_BOTTLE: - return HasBottle; + return HasBottle(); } SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", static_cast(itemName)); assert(false); @@ -232,7 +238,7 @@ namespace Rando { // Adult items // TODO: Uncomment those if we ever implement more item usability settings case RG_FAIRY_BOW: - return IsAdult;// || BowAsChild; + return IsAdult && (AmmoCanDrop || GetInLogic(LOGIC_BUY_ARROW));// || BowAsChild; case RG_MEGATON_HAMMER: return IsAdult;// || HammerAsChild; case RG_IRON_BOOTS: @@ -266,7 +272,7 @@ namespace Rando { // Child items case RG_FAIRY_SLINGSHOT: - return IsChild;// || SlingshotAsAdult; + return IsChild && (AmmoCanDrop || GetInLogic(LOGIC_BUY_SEED));// || SlingshotAsAdult; case RG_BOOMERANG: return IsChild;// || BoomerangAsAdult; case RG_KOKIRI_SWORD: @@ -279,65 +285,70 @@ namespace Rando { return IsChild;// || DekuShieldAsAdult; case RG_WEIRD_EGG: return IsChild; + case RG_PROGRESSIVE_BOMB_BAG: + case RG_BOMB_BAG: + return AmmoCanDrop || GetInLogic(LOGIC_BUY_BOMB); case RG_PROGRESSIVE_BOMBCHUS: case RG_BOMBCHU_5: case RG_BOMBCHU_10: case RG_BOMBCHU_20: - return BombchuRefill && BombchusEnabled; + return BombchuRefill() && BombchusEnabled(); case RG_RUTOS_LETTER: return IsChild; // Adult Trade case RG_POCKET_EGG: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_COJIRO)); case RG_COJIRO: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_ODD_MUSHROOM)); case RG_ODD_MUSHROOM: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_ODD_POTION)); case RG_ODD_POTION: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_POACHERS_SAW)); case RG_POACHERS_SAW: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_BROKEN_SWORD)); case RG_BROKEN_SWORD: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_PRESCRIPTION)); case RG_PRESCRIPTION: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_EYEBALL_FROG)); case RG_EYEBALL_FROG: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_EYEDROPS)); case RG_EYEDROPS: - return IsAdult; + return IsAdult || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && CanUse(RG_CLAIM_CHECK)); case RG_CLAIM_CHECK: return IsAdult; // Songs case RG_ZELDAS_LULLABY: - return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); case RG_EPONAS_SONG: - return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); case RG_SARIAS_SONG: - return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SUNS_SONG: - return Ocarina && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SONG_OF_TIME: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SONG_OF_STORMS: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_MINUET_OF_FOREST: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); case RG_BOLERO_OF_FIRE: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SERENADE_OF_WATER: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_REQUIEM_OF_SPIRIT: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_NOCTURNE_OF_SHADOW: - return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_PRELUDE_OF_LIGHT: - return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); // Misc. Items case RG_FISHING_POLE: return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies + case RG_EPONA: + return IsAdult && CanUse(RG_EPONAS_SONG); // Bottle Items case RG_BOTTLE_WITH_BUGS: @@ -350,17 +361,19 @@ namespace Rando { return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS); // Magic items + case RG_MAGIC_SINGLE: + return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); default: - return MagicMeter && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(RG_FAIRY_BOW))); + return CanUse(RG_MAGIC_SINGLE) && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(RG_FAIRY_BOW))); } } bool Logic::HasProjectile(HasProjectileAge age) { - return HasExplosives || - (age == HasProjectileAge::Child && (Slingshot || Boomerang)) || - (age == HasProjectileAge::Adult && (Hookshot || Bow )) || - (age == HasProjectileAge::Both && (Slingshot || Boomerang) && (Hookshot || Bow)) || - (age == HasProjectileAge::Either && (Slingshot || Boomerang || Hookshot || Bow)); + return HasExplosives() || + (age == HasProjectileAge::Child && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))) || + (age == HasProjectileAge::Adult && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) )) || + (age == HasProjectileAge::Both && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)) && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))) || + (age == HasProjectileAge::Either && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))); } bool Logic::HasBossSoul(RandomizerGet itemName) { @@ -407,32 +420,117 @@ namespace Rando { return ((IsAdult && HasItem(RG_DINS_FIRE)) || (IsChild && (HasItem(RG_STICKS) || HasItem(RG_DINS_FIRE)))) && false; //GlitchEquipSwapDins; case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) || - HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle || CanUse(RG_NUTS) || Ocarina || HasItem(RG_LENS_OF_TRUTH) || HasExplosives || - ctx->GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; + HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle() || CanUse(RG_NUTS) || HasItem(RG_FAIRY_OCARINA) || HasItem(RG_LENS_OF_TRUTH) || HasExplosives() || + GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; } //Shouldn't be reached return false; } - bool Logic::CanKillEnemy(std::string enemy) { - //switch(enemy) {} RANDOTODO implement enemies enum - if (enemy == "Big Skulltula"){ - return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE) || HasExplosives; + bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance) { + switch(enemy) { + case RE_GOLD_SKULLTULA: + case RE_GOHMA_LARVA: + case RE_MAD_SCRUB: + return CanAttack(); + case RE_BIG_SKULLTULA: + return CanDamage() || CanUse(RG_HOOKSHOT); + case RE_DODONGO: + case RE_LIZALFOS: + return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_MEGATON_HAMMER); + case RE_KEESE: + case RE_FIRE_KEESE: + return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); + default: + SPDLOG_ERROR("CanKillEnemy reached `default`."); + assert(false); + return false; } - //Shouldn't be reached - return false; } - bool Logic::CanPassEnemy(std::string enemy) { - //switch(enemy) {} RANDOTODO implement enemies enum + bool Logic::CanPassEnemy(RandomizerEnemy enemy) { if (CanKillEnemy(enemy)){ return true; } - if (enemy == "Big Skulltula"){ - return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); + switch(enemy) { + case RE_GOLD_SKULLTULA: + case RE_GOHMA_LARVA: + case RE_LIZALFOS: + case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors? + case RE_MAD_SCRUB: + case RE_KEESE: + case RE_FIRE_KEESE: + return true; + case RE_BIG_SKULLTULA: + return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); + default: + SPDLOG_ERROR("CanPassEnemy reached `default`."); + assert(false); + return false; } - return false; + } + + bool Logic::CanAvoidEnemy(RandomizerEnemy enemy) { + if (CanKillEnemy(enemy)){ + return true; + } + switch(enemy) { + case RE_GOLD_SKULLTULA: + case RE_GOHMA_LARVA: + case RE_LIZALFOS: + case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors? + case RE_BIG_SKULLTULA: + return true; + case RE_MAD_SCRUB: + case RE_KEESE: + case RE_FIRE_KEESE: + return CanUse(RG_NUTS); + default: + SPDLOG_ERROR("CanPassEnemy reached `default`."); + assert(false); + return false; + } + } + + bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) { + if (!CanKillEnemy(enemy, distance)){ + return false; + } + if (distance <= ED_MASTER_SWORD_JUMPSLASH){ + return true; + } + switch(enemy) { + case RE_GOLD_SKULLTULA: + //RANDOTODO double check all jumpslash kills that might be out of jump/backflip range + return distance <= ED_HAMMER_JUMPSLASH || (distance <= ED_RANG_OR_HOOKSHOT && (CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))) || (distance == ED_LONGSHOT && CanUse(RG_LONGSHOT)); + case RE_KEESE: + case RE_FIRE_KEESE: + return true; + default: + return aboveLink || (distance <= ED_RANG_OR_HOOKSHOT && CanUse(RG_BOOMERANG)); + } + } + + bool Logic::CanBreakMudWalls() { + //RANDOTODO blue fire tricks + return BlastOrSmash(); + } + + bool Logic::CanGetDekuBabaSticks() { + return DekuBabaSticks || (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG)); + } + + bool Logic::CanHitEyeTargets() { + return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT); + } + + bool Logic::CanDetonateBombFlowers() { + return CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_DINS_FIRE); + } + + bool Logic::CanDetonateUprightBombFlower() { + return CanDetonateBombFlowers() || CanUse(RG_GORONS_BRACELET); } Logic::Logic() { @@ -441,221 +539,190 @@ namespace Rando { uint8_t Logic::BottleCount() { uint8_t count = 0; + if (!CanEmptyBigPoes){ + return 0; + } for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) { - uint8_t item = ctx->GetSaveContext()->inventory.items[i]; - if (item != ITEM_NONE && (item != ITEM_LETTER_RUTO || (item == ITEM_LETTER_RUTO && DeliverLetter)) && item != ITEM_BIG_POE) { + uint8_t item = GetSaveContext()->inventory.items[i]; + if (item != ITEM_NONE && (item != ITEM_LETTER_RUTO || (item == ITEM_LETTER_RUTO && DeliverLetter))) { count++; } } return count; } - // Updates all logic helpers. Should be called whenever a non-helper is changed - void Logic::UpdateHelpers() { - OcarinaButtons = (HasItem(RG_OCARINA_A_BUTTON) ? 1 : 0) + - (HasItem(RG_OCARINA_C_LEFT_BUTTON) ? 1 : 0) + - (HasItem(RG_OCARINA_C_RIGHT_BUTTON) ? 1 : 0) + - (HasItem(RG_OCARINA_C_UP_BUTTON) ? 1 : 0) + - (HasItem(RG_OCARINA_C_DOWN_BUTTON) ? 1 : 0); - ZeldasLetter = HasItem(RG_ZELDAS_LETTER); - WeirdEgg = CanUse(RG_WEIRD_EGG); - BuySeed = GetInLogic(LOGIC_BUY_SEED); - BuyArrow = GetInLogic(LOGIC_BUY_ARROW); - BuyBomb = GetInLogic(LOGIC_BUY_BOMB); - BuyMagicPotion = GetInLogic(LOGIC_BUY_MAGIC_POTION); - MagicBean = ctx->GetAmmo(ITEM_BEAN) > 0; - RutosLetter = CanUse(RG_RUTOS_LETTER); - Boomerang = CanUse(RG_BOOMERANG); - DinsFire = CanUse(RG_DINS_FIRE); - FaroresWind = CanUse(RG_FARORES_WIND); - NayrusLove = CanUse(RG_NAYRUS_LOVE); - LensOfTruth = CanUse(RG_LENS_OF_TRUTH); - ShardOfAgony = HasItem(RG_STONE_OF_AGONY); - //SkullMask = false; - //MaskOfTruth = false; + uint8_t Logic::OcarinaButtons(){ + return HasItem(RG_OCARINA_A_BUTTON) + HasItem(RG_OCARINA_C_LEFT_BUTTON) + HasItem(RG_OCARINA_C_RIGHT_BUTTON) + HasItem(RG_OCARINA_C_UP_BUTTON) + HasItem(RG_OCARINA_C_DOWN_BUTTON); + } - //Adult logic - Hammer = CanUse(RG_MEGATON_HAMMER); - IronBoots = CanUse(RG_IRON_BOOTS); - HoverBoots = CanUse(RG_HOVER_BOOTS); - DekuShield = CanUse(RG_DEKU_SHIELD); - HylianShield = CanUse(RG_HYLIAN_SHIELD); - MirrorShield = CanUse(RG_MIRROR_SHIELD); - GoronTunic = CanUse(RG_GORON_TUNIC); - ZoraTunic = CanUse(RG_ZORA_TUNIC); - //Epona = false; - //BigPoe = false; - GerudoToken = HasItem(RG_GERUDO_MEMBERSHIP_CARD); - FireArrows = CanUse(RG_FIRE_ARROWS); - IceArrows = CanUse(RG_ICE_ARROWS); - LightArrows = CanUse(RG_LIGHT_ARROWS); - KokiriSword = CanUse(RG_KOKIRI_SWORD); - MasterSword = CanUse(RG_MASTER_SWORD); - BiggoronSword = CanUse(RG_BIGGORON_SWORD); - NumBottles = ((NoBottles) ? 0 : BottleCount()); - HasBottle = NumBottles >= 1; - Slingshot = CanUse(RG_FAIRY_SLINGSHOT) && (BuySeed || AmmoCanDrop); - Ocarina = HasItem(RG_FAIRY_OCARINA); - OcarinaOfTime = HasItem(RG_OCARINA_OF_TIME); - MagicMeter = HasItem(RG_MAGIC_SINGLE) && (AmmoCanDrop || (HasBottle && BuyMagicPotion)); - BombBag = HasItem(RG_BOMB_BAG) && (BuyBomb || AmmoCanDrop); - BombchusEnabled = ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) ? ctx->CheckInventory(ITEM_BOMBCHU, true) : BombBag; - BuyBombchus = (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant); - Hookshot = CanUse(RG_HOOKSHOT); - Longshot = CanUse(RG_LONGSHOT); - Bow = CanUse(RG_FAIRY_BOW) && (BuyArrow || AmmoCanDrop); - GoronBracelet = HasItem(RG_GORONS_BRACELET); - SilverGauntlets = HasItem(RG_SILVER_GAUNTLETS); - GoldenGauntlets = HasItem(RG_GOLDEN_GAUNTLETS); - Swim = HasItem(RG_BRONZE_SCALE); - SilverScale = HasItem(RG_SILVER_SCALE); - GoldScale = HasItem(RG_GOLDEN_SCALE); - ChildsWallet = HasItem(RG_CHILD_WALLET); - AdultsWallet = HasItem(RG_ADULT_WALLET); - BiggoronSword = HasItem(RG_BIGGORON_SWORD); - - ProgressiveScale = ctx->CurrentUpgrade(UPG_SCALE) + HasItem(RG_BRONZE_SCALE); - ProgressiveWallet = ctx->CurrentUpgrade(UPG_WALLET) + HasItem(RG_CHILD_WALLET); - - CanSummonGohma = HasBossSoul(RG_GOHMA_SOUL); - CanSummonKingDodongo = HasBossSoul(RG_KING_DODONGO_SOUL); - CanSummonBarinade = HasBossSoul(RG_BARINADE_SOUL); - CanSummonPhantomGanon = HasBossSoul(RG_PHANTOM_GANON_SOUL); - CanSummonVolvagia = HasBossSoul(RG_VOLVAGIA_SOUL); - CanSummonMorpha = HasBossSoul(RG_MORPHA_SOUL); - CanSummonBongoBongo = HasBossSoul(RG_BONGO_BONGO_SOUL); - CanSummonTwinrova = HasBossSoul(RG_TWINROVA_SOUL); - CanSummonGanon = HasBossSoul(RG_GANON_SOUL); - - // Boss Keys - BossKeyForestTemple = HasItem(RG_FOREST_TEMPLE_BOSS_KEY); - BossKeyFireTemple = HasItem(RG_FIRE_TEMPLE_BOSS_KEY); - BossKeyWaterTemple = HasItem(RG_WATER_TEMPLE_BOSS_KEY); - BossKeySpiritTemple = HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); - BossKeyShadowTemple = HasItem(RG_SHADOW_TEMPLE_BOSS_KEY); - BossKeyGanonsCastle = HasItem(RG_GANONS_CASTLE_BOSS_KEY); - - KokiriEmerald = HasItem(RG_KOKIRI_EMERALD); - GoronRuby = HasItem(RG_GORON_RUBY); - ZoraSapphire = HasItem(RG_ZORA_SAPPHIRE); - ForestMedallion = HasItem(RG_FOREST_MEDALLION); - FireMedallion = HasItem(RG_FIRE_MEDALLION); - WaterMedallion = HasItem(RG_WATER_MEDALLION); - SpiritMedallion = HasItem(RG_SPIRIT_MEDALLION); - ShadowMedallion = HasItem(RG_SHADOW_MEDALLION); - LightMedallion = HasItem(RG_LIGHT_MEDALLION); - - DoubleDefense = HasItem(RG_DOUBLE_DEFENSE); - TriforcePieces = ctx->GetSaveContext()->triforcePiecesCollected; - Greg = HasItem(RG_GREG_RUPEE); - GoldSkulltulaTokens = ctx->GetGSCount(); - - //you need at least 2 buttons for scarecrow song - ScarecrowSong = ScarecrowSong || (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && Ocarina && OcarinaButtons >= 2) || (ChildScarecrow && AdultScarecrow); - Scarecrow = Hookshot && ScarecrowSong; - DistantScarecrow = Longshot && ScarecrowSong; - - // TODO: Implement Ammo Drop Setting in place of bombchu drops - BombchuRefill = BuyBombchus || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/)); - - //Usage - Bombs = HasItem(RG_PROGRESSIVE_BOMB_BAG); - BlueFire = CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); - - // TODO: Implement Ammo Drop Setting in place of bombchu drops - HasExplosives = Bombs || CanUse(RG_BOMBCHU_5); - HasBoots = IronBoots || HoverBoots; - //Unshuffled adult trade quest - ClaimCheck = CanUse(RG_CLAIM_CHECK); - Eyedrops = CanUse(RG_EYEDROPS) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && ClaimCheck); - EyeballFrog = CanUse(RG_EYEBALL_FROG) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Eyedrops); - Prescription = CanUse(RG_PRESCRIPTION) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && EyeballFrog); - BrokenSword = CanUse(RG_BROKEN_SWORD) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Prescription); - PoachersSaw = CanUse(RG_POACHERS_SAW) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && BrokenSword); - OddPoultice = CanUse(RG_ODD_POTION) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && PoachersSaw); - OddMushroom = CanUse(RG_ODD_MUSHROOM) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddPoultice); - Cojiro = CanUse(RG_COJIRO) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddMushroom); - PocketEgg = CanUse(RG_POCKET_EGG) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Cojiro); - - // IsChild = Age == AGE_CHILD; - // IsAdult = Age == AGE_ADULT; - - CanBlastOrSmash = HasExplosives || CanUse(RG_MEGATON_HAMMER); - CanChildAttack = IsChild && (Slingshot || Boomerang || CanUse(RG_STICKS) || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD)); - CanChildDamage = IsChild && (Slingshot || CanUse(RG_STICKS) || KokiriSword || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD)); - CanAdultAttack = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword || Hookshot); - CanAdultDamage = IsAdult && (CanUse(RG_FAIRY_BOW) || CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || HasExplosives || CanUse(RG_DINS_FIRE) || MasterSword || Hammer || BiggoronSword); - CanStunDeku = CanAdultAttack || CanChildAttack || CanUse(RG_NUTS) || HasShield; - CanCutShrubs = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD); - CanDive = ProgressiveScale >= 2; - CanLeaveForest = ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); - CanPlantBugs = IsChild && CanUse(RG_BOTTLE_WITH_BUGS); - CanRideEpona = IsAdult && Epona && CanUse(RG_EPONAS_SONG); - CanSummonGossipFairyWithoutSuns = CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); - CanSummonGossipFairy = CanSummonGossipFairyWithoutSuns || CanUse(RG_SUNS_SONG); - Hearts = ctx->GetSaveContext()->healthCapacity / 16; - EffectiveHealth = ((Hearts << (2 + DoubleDefense)) >> Multiplier) + ((Hearts << (2 + DoubleDefense)) % (1 << Multiplier) > 0); //Number of half heart hits to die, ranges from 1 to 160 - FireTimer = CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0; - WaterTimer = CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0; - NeedNayrusLove = (EffectiveHealth == 1); - CanSurviveDamage = !NeedNayrusLove || CanUse(RG_NAYRUS_LOVE); - CanTakeDamage = CanUse(RG_BOTTLE_WITH_FAIRY) || CanSurviveDamage; - CanTakeDamageTwice = (CanUse(RG_BOTTLE_WITH_FAIRY) && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(RG_NAYRUS_LOVE) || CanUse(RG_BOTTLE_WITH_FAIRY))) || (EffectiveHealth > 2); - CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); - CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); - HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); - CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); - CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)); - CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs; - CanFish = ChildsWallet && (HasItem(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)); - CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))); - CanGetAdultFish = CanFish && IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT); - - GuaranteeTradePath = ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetTrickOption(RT_DMT_BOLERO_BIGGORON) || CanBlastOrSmash || StopGCRollingGoronAsAdult; - //GuaranteeHint = (hints == "Mask" && MaskofTruth) || (hints == "Agony") || (hints != "Mask" && hints != "Agony"); - HasFireSource = CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); - HasFireSourceWithTorch = HasFireSource || CanUse(RG_STICKS); - - //Gerudo Fortress - CanFinishGerudoFortress = (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (GerudoToken || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_NORMAL) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_FAST)); - - HasShield = CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); //Mirror shield can't reflect attacks - CanShield = CanUse(RG_MIRROR_SHIELD) || HasShield; - ChildShield = IsChild && CanUse(RG_DEKU_SHIELD); //hylian shield is not helpful for child - AdultReflectShield = IsAdult && CanUse(RG_HYLIAN_SHIELD); //Mirror shield can't reflect attacks - AdultShield = IsAdult && (CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_MIRROR_SHIELD)); - CanShieldFlick = ChildShield || AdultShield; - CanJumpslash = CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); // Not including hammer as hammer jump attacks can be weird - CanUseProjectile = HasExplosives || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG); - CanUseMagicArrow = CanUse(RG_FIRE_ARROWS) || CanUse(RG_ICE_ARROWS) || CanUse(RG_LIGHT_ARROWS); - - //Bridge and LACS Requirements - MedallionCount = (ForestMedallion ? 1:0) + (FireMedallion ? 1:0) + (WaterMedallion ? 1:0) + (SpiritMedallion ? 1:0) + (ShadowMedallion ? 1:0) + (LightMedallion ? 1:0); - StoneCount = (KokiriEmerald ? 1:0) + (GoronRuby ? 1:0) + (ZoraSapphire ? 1:0); - DungeonCount = (DekuTreeClear ? 1:0) + (DodongosCavernClear ? 1:0) + (JabuJabusBellyClear ? 1:0) + (ForestTempleClear ? 1:0) + (FireTempleClear ? 1:0) + (WaterTempleClear ? 1:0) + (SpiritTempleClear ? 1:0) + (ShadowTempleClear ? 1:0); - HasAllStones = StoneCount == 3; - HasAllMedallions = MedallionCount == 6; - GregInBridgeLogic = ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG); - GregInLacsLogic = ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD); - - CanBuildRainbowBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && ShadowMedallion && SpiritMedallion && LightArrows) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount + (Greg && GregInBridgeLogic ? 1 : 0) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount + (Greg && GregInBridgeLogic ? 1 : 0) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount + MedallionCount + (Greg && GregInBridgeLogic ? 1 : 0) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount + (Greg && GregInBridgeLogic ? 1 : 0) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GoldSkulltulaTokens >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && Greg); - - CanTriggerLACS = (ctx->GetSettings()->LACSCondition() == RO_LACS_VANILLA && ShadowMedallion && SpiritMedallion) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_STONES && StoneCount + (Greg && GregInLacsLogic ? 1 : 0) >= ctx->GetOption(RSK_LACS_STONE_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount + (Greg && GregInLacsLogic ? 1 : 0) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_REWARDS && StoneCount + MedallionCount + (Greg && GregInLacsLogic ? 1 : 0) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount + (Greg && GregInLacsLogic ? 1 : 0) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS && GoldSkulltulaTokens >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value()); - CanCompleteTriforce = TriforcePieces >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Value(); + bool Logic::HasBottle(){ + return BottleCount() >= 1; + } + + bool Logic::CanJumpslash() { + // Not including hammer as hammer jump attacks can be weird; + return CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); + } + + bool Logic::CanDamage() { + return CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash() || BlastOrSmash() || CanUse(RG_DINS_FIRE) || CanUse(RG_FAIRY_BOW); + } + + bool Logic::CanAttack() { + return CanDamage() || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); + } + + bool Logic::BombchusEnabled(){ + return ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) ? CheckInventory(ITEM_BOMBCHU, true) : HasItem(RG_BOMB_BAG); + } + + // TODO: Implement Ammo Drop Setting in place of bombchu drops + bool Logic::BombchuRefill(){ + return GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/)); + } + + bool Logic::HookshotOrBoomerang(){ + return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); + } + + bool Logic::ScarecrowsSong(){ + return (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) + || (ChildScarecrow && AdultScarecrow); + } + + bool Logic::BlueFire(){ + return CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); + } + + bool Logic::HasExplosives(){ + return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); + } + + bool Logic::BlastOrSmash(){ + return HasExplosives() || CanUse(RG_MEGATON_HAMMER); + } + + bool Logic::CanSpawnSoilSkull(){ + return IsChild && CanUse(RG_BOTTLE_WITH_BUGS); + } + + bool Logic::CanReflectNuts(){ + return CanUse(RG_DEKU_SHIELD) || (IsAdult && CanUse(RG_HYLIAN_SHIELD)); + } + + bool Logic::CanCutShrubs(){ + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives() || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD); + } + + bool Logic::CanStunDeku(){ + return CanAttack() || CanUse(RG_NUTS) || CanReflectNuts(); + } + + bool Logic::CanLeaveForest(){ + return ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); + } + + bool Logic::CallGossipFairyExceptSuns(){ + return CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); + } + + bool Logic::CallGossipFairy(){ + return CallGossipFairyExceptSuns() || CanUse(RG_SUNS_SONG); + } + + uint8_t Logic::EffectiveHealth(){ + uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() : 10; + return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) + ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) % (1 << Multiplier) > 0); + } + + uint8_t Logic::Hearts(){ + return GetSaveContext()->healthCapacity / 16; + } + + uint8_t Logic::DungeonCount(){ + return DekuTreeClear + DodongosCavernClear + JabuJabusBellyClear + ForestTempleClear + FireTempleClear + WaterTempleClear + SpiritTempleClear + ShadowTempleClear; + } + + uint8_t Logic::StoneCount(){ + return HasItem(RG_KOKIRI_EMERALD) + HasItem(RG_GORON_RUBY) + HasItem(RG_ZORA_SAPPHIRE); + } + + uint8_t Logic::MedallionCount(){ + return HasItem(RG_FOREST_MEDALLION) + HasItem(RG_FIRE_MEDALLION) + HasItem(RG_WATER_MEDALLION) + HasItem(RG_SPIRIT_MEDALLION) + HasItem(RG_SHADOW_MEDALLION) + HasItem(RG_LIGHT_MEDALLION); + } + + uint8_t Logic::FireTimer(){ + return CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; + } + + uint8_t Logic::WaterTimer(){ + return CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; + } + + bool Logic::TakeDamage(){ + return CanUse(RG_BOTTLE_WITH_FAIRY) || EffectiveHealth() != 1 || CanUse(RG_NAYRUS_LOVE); + } + + bool Logic::CanOpenBombGrotto(){ + return BlastOrSmash() && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); + } + + bool Logic::CanOpenStormsGrotto(){ + return CanUse(RG_SONG_OF_STORMS) && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); + } + + bool Logic::CanGetNightTimeGS(){ + return CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG); + } + + bool Logic::CanBreakUpperBeehives(){ + return HookshotOrBoomerang() || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)); + } + + bool Logic::CanBreakLowerBeehives(){ + return CanBreakUpperBeehives() || CanUse(RG_BOMB_BAG); + } + + bool Logic::HasFireSource(){ + return CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); + } + + bool Logic::HasFireSourceWithTorch(){ + return HasFireSource() || CanUse(RG_STICKS); + } + + bool Logic::CanFinishGerudoFortress(){ + return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || + (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) || + ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN); + } + + bool Logic::CanShield(){ + return CanUse(RG_MIRROR_SHIELD) || CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); + } + + bool Logic::CanUseProjectile(){ + return HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG); + } + + bool Logic::CanBuildRainbowBridge(){ + return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION) && CanUse(RG_LIGHT_ARROWS)) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE)); + } + + bool Logic::CanTriggerLACS(){ + return (ctx->GetSettings()->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).Value()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).Value()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value()); } bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { @@ -672,91 +739,832 @@ namespace Rando { (GetDifficultyValueFromString(GlitchHover) >= static_cast(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= static_cast(GlitchDifficulty::INTERMEDIATE)))) { return ForestTempleKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_FOREST_TEMPLE) >= requiredAmountGlitchless; + 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; }*/ - return ctx->GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless; case RR_WATER_TEMPLE: /*if (IsGlitched && (false)) { return WaterTempleKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless; case RR_SPIRIT_TEMPLE: /*if (IsGlitched && (false)) { return SpiritTempleKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless; case RR_SHADOW_TEMPLE: /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= static_cast(GlitchDifficulty::NOVICE))) { return ShadowTempleKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless; case RR_BOTTOM_OF_THE_WELL: /*if (IsGlitched && (false)) { return BottomOfTheWellKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; case RR_GERUDO_TRAINING_GROUNDS: /*if (IsGlitched && (false)) { return GerudoTrainingGroundsKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless; case RR_GANONS_CASTLE: /*if (IsGlitched && (false)) { return GanonsCastleKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless; case RR_MARKET_TREASURE_CHEST_GAME: /*if (IsGlitched && (false)) { return TreasureGameKeys >= requiredAmountGlitched; }*/ - return ctx->GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless; case RR_GERUDO_FORTRESS: - return ctx->GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless; + return GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless; default: return false; } } - bool Logic::EventsUpdated() { - if (DekuTreeClearPast != DekuTreeClear || - GoronRubyPast != GoronRuby || - ZoraSapphirePast != ZoraSapphire || - ForestTrialClearPast != ForestTrialClear || - FireTrialClearPast != FireTrialClear || - WaterTrialClearPast != WaterTrialClear || - ShadowTrialClearPast != ShadowTrialClear || - SpiritTrialClearPast != SpiritTrialClear || - LightTrialClearPast != LightTrialClear || - DrainWellPast != DrainWell || - DampesWindmillAccessPast != DampesWindmillAccess || - TimeTravelPast != TimeTravel) { - DekuTreeClearPast = DekuTreeClear; - GoronRubyPast = GoronRuby; - ZoraSapphirePast = ZoraSapphire; - ForestTrialClearPast = ForestTrialClear; - FireTrialClearPast = FireTrialClear; - WaterTrialClearPast = WaterTrialClear; - ShadowTrialClearPast = ShadowTrialClear; - SpiritTrialClearPast = SpiritTrialClear; - LightTrialClearPast = LightTrialClear; - DrainWellPast = DrainWell; - DampesWindmillAccessPast = DampesWindmillAccess; - return true; + std::map Logic::RandoGetToEquipFlag = { + { RG_KOKIRI_SWORD, EQUIP_FLAG_SWORD_KOKIRI }, + { RG_MASTER_SWORD, EQUIP_FLAG_SWORD_MASTER }, + { RG_BIGGORON_SWORD, EQUIP_FLAG_SWORD_BGS }, + { RG_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, + { RG_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, + { RG_MIRROR_SHIELD, EQUIP_FLAG_SHIELD_MIRROR }, + { RG_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, + { RG_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, + { RG_BUY_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, + { RG_BUY_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, + { RG_BUY_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, + { RG_BUY_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, + { RG_IRON_BOOTS, EQUIP_FLAG_BOOTS_IRON }, + { RG_HOVER_BOOTS, EQUIP_FLAG_BOOTS_HOVER } + }; + + std::map Logic::RandoGetToRandInf = { + { RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER }, + { RG_WEIRD_EGG, RAND_INF_WEIRD_EGG }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND } + }; + + std::map Logic::RandoGetToDungeonScene = { + { RG_FOREST_TEMPLE_SMALL_KEY, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_SMALL_KEY, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_SMALL_KEY, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, + { RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, + { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, + { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_KEY_RING, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, + { RG_GERUDO_TRAINING_GROUNDS_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, + { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, + { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_BOSS_KEY, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_BOSS_KEY, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_BOSS_KEY, SCENE_SHADOW_TEMPLE }, + { RG_GANONS_CASTLE_BOSS_KEY, SCENE_INSIDE_GANONS_CASTLE }, + { RG_DEKU_TREE_MAP, SCENE_DEKU_TREE }, + { RG_DODONGOS_CAVERN_MAP, SCENE_DODONGOS_CAVERN }, + { RG_JABU_JABUS_BELLY_MAP, SCENE_JABU_JABU }, + { RG_FOREST_TEMPLE_MAP, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_MAP, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_MAP, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_MAP, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_MAP, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_MAP, SCENE_BOTTOM_OF_THE_WELL }, + { RG_ICE_CAVERN_MAP, SCENE_ICE_CAVERN }, + { RG_DEKU_TREE_COMPASS, SCENE_DEKU_TREE }, + { RG_DODONGOS_CAVERN_COMPASS, SCENE_DODONGOS_CAVERN }, + { RG_JABU_JABUS_BELLY_COMPASS, SCENE_JABU_JABU }, + { RG_FOREST_TEMPLE_COMPASS, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_COMPASS, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_COMPASS, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_COMPASS, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_COMPASS, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_COMPASS, SCENE_BOTTOM_OF_THE_WELL }, + { RG_ICE_CAVERN_COMPASS, SCENE_ICE_CAVERN }, + { RG_TREASURE_GAME_SMALL_KEY, SCENE_TREASURE_BOX_SHOP } + }; + + std::map Logic::RandoGetToQuestItem = { + { RG_FOREST_MEDALLION, QUEST_MEDALLION_FOREST }, + { RG_FIRE_MEDALLION, QUEST_MEDALLION_FIRE }, + { RG_WATER_MEDALLION, QUEST_MEDALLION_WATER }, + { RG_SPIRIT_MEDALLION, QUEST_MEDALLION_SPIRIT }, + { RG_SHADOW_MEDALLION, QUEST_MEDALLION_SHADOW }, + { RG_LIGHT_MEDALLION, QUEST_MEDALLION_LIGHT }, + { RG_MINUET_OF_FOREST, QUEST_SONG_MINUET }, + { RG_BOLERO_OF_FIRE, QUEST_SONG_BOLERO }, + { RG_SERENADE_OF_WATER, QUEST_SONG_SERENADE }, + { RG_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM }, + { RG_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE }, + { RG_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE }, + { RG_ZELDAS_LULLABY, QUEST_SONG_LULLABY }, + { RG_EPONAS_SONG, QUEST_SONG_EPONA }, + { RG_SARIAS_SONG, QUEST_SONG_SARIA }, + { RG_SUNS_SONG, QUEST_SONG_SUN }, + { RG_SONG_OF_TIME, QUEST_SONG_TIME }, + { RG_SONG_OF_STORMS, QUEST_SONG_STORMS }, + { RG_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, + { RG_GORON_RUBY, QUEST_GORON_RUBY }, + { RG_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, + { RG_STONE_OF_AGONY, QUEST_STONE_OF_AGONY }, + { RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD }, + }; + + uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT }; + uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME }; + + void Logic::ApplyItemEffect(Item& item, bool state) { + auto randoGet = item.GetRandomizerGet(); + if (item.GetGIEntry()->objectId == OBJECT_GI_STICK) { + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); } - return false; + if (item.GetGIEntry()->objectId == OBJECT_GI_NUTS) { + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + } + switch (item.GetItemType()) { + case ITEMTYPE_ITEM: + { + switch (randoGet) { + case RG_STONE_OF_AGONY: + case RG_GERUDO_MEMBERSHIP_CARD: + SetQuestItem(RandoGetToQuestItem.at(randoGet), state); + break; + case RG_WEIRD_EGG: + SetRandoInf(RAND_INF_WEIRD_EGG, state); + break; + case RG_ZELDAS_LETTER: + SetRandoInf(RAND_INF_ZELDAS_LETTER, state); + break; + case RG_DOUBLE_DEFENSE: + mSaveContext->isDoubleDefenseAcquired = state; + break; + case RG_POCKET_EGG: + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + SetAdultTrade(item.GetGIEntry()->itemId, state); + break; + case RG_PROGRESSIVE_HOOKSHOT: + { + uint8_t i; + for (i = 0; i < 3; i++) { + if (CurrentInventory(ITEM_HOOKSHOT) == HookshotLookup[i]) { + break; + } + } + auto newItem = i + (!state ? -1 : 1); + if (newItem < 0) { + newItem = 0; + } + else if (newItem > 2) { + newItem = 2; + } + SetInventory(ITEM_HOOKSHOT, HookshotLookup[newItem]); + } break; + case RG_PROGRESSIVE_STRENGTH: + { + auto currentLevel = CurrentUpgrade(UPG_STRENGTH); + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_STRENGTH, newLevel); + } break; + case RG_PROGRESSIVE_BOMB_BAG: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BOMB_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BOMB_BAG, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_BOMB_BAG); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_BOMB, (!state ? ITEM_NONE : ITEM_BOMB)); + } + SetUpgrade(UPG_BOMB_BAG, newLevel); + } break; + case RG_PROGRESSIVE_BOW: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_QUIVER_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_QUIVER, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_QUIVER); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_BOW, (!state ? ITEM_NONE : ITEM_BOW)); + } + SetUpgrade(UPG_QUIVER, newLevel); + } break; + case RG_PROGRESSIVE_SLINGSHOT: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BULLET_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BULLET_BAG, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_BULLET_BAG); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_SLINGSHOT, (!state ? ITEM_NONE : ITEM_SLINGSHOT)); + } + SetUpgrade(UPG_BULLET_BAG, newLevel); + } break; + case RG_PROGRESSIVE_WALLET: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_WALLET_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_MONEY, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_WALLET); + if (!CheckRandoInf(RAND_INF_HAS_WALLET) && state) { + SetRandoInf(RAND_INF_HAS_WALLET, true); + } + else if (currentLevel == 0 && !state) { + SetRandoInf(RAND_INF_HAS_WALLET, false); + } + else { + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_WALLET, newLevel); + } + } break; + case RG_PROGRESSIVE_SCALE: + { + auto currentLevel = CurrentUpgrade(UPG_SCALE); + if (!CheckRandoInf(RAND_INF_CAN_SWIM) && state) { + SetRandoInf(RAND_INF_CAN_SWIM, true); + } + else if (currentLevel == 0 && !state) { + SetRandoInf(RAND_INF_CAN_SWIM, false); + } + else { + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_SCALE, newLevel); + } + } break; + case RG_PROGRESSIVE_NUT_UPGRADE: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_NUT_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_NUTS); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + } + SetUpgrade(UPG_NUTS, newLevel); + } break; + case RG_PROGRESSIVE_STICK_UPGRADE: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_STICK_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_STICKS); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); + } + SetUpgrade(UPG_STICKS, newLevel); + } break; + case RG_PROGRESSIVE_BOMBCHUS: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BOMBCHU_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BOMBCHUS, true); + break; + } + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + } break; + case RG_PROGRESSIVE_MAGIC_METER: + { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_MAGIC_METER, true); + break; + } + mSaveContext->magicLevel += (!state ? -1 : 1); + } break; + case RG_PROGRESSIVE_OCARINA: + { + uint8_t i; + for (i = 0; i < 3; i++) { + if (CurrentInventory(ITEM_OCARINA_FAIRY) == OcarinaLookup[i]) { + break; + } + } + i += (!state ? -1 : 1); + if (i < 0) { + i = 0; + } + else if (i > 2) { + i = 2; + } + SetInventory(ITEM_OCARINA_FAIRY, OcarinaLookup[i]); + } break; + case RG_HEART_CONTAINER: + mSaveContext->healthCapacity += (!state ? -16 : 16); + break; + case RG_PIECE_OF_HEART: + mSaveContext->healthCapacity += (!state ? -4 : 4); + break; + case RG_BOOMERANG: + case RG_LENS_OF_TRUTH: + case RG_MEGATON_HAMMER: + case RG_DINS_FIRE: + case RG_FARORES_WIND: + case RG_NAYRUS_LOVE: + case RG_FIRE_ARROWS: + case RG_ICE_ARROWS: + case RG_LIGHT_ARROWS: + SetInventory(item.GetGIEntry()->itemId, (!state ? ITEM_NONE : item.GetGIEntry()->itemId)); + break; + case RG_MAGIC_BEAN: + case RG_MAGIC_BEAN_PACK: + { + auto change = (item.GetRandomizerGet() == RG_MAGIC_BEAN ? 1 : 10); + auto current = GetAmmo(ITEM_BEAN); + SetAmmo(ITEM_BEAN, current + (!state ? -change : change)); + } break; + case RG_EMPTY_BOTTLE: + case RG_BOTTLE_WITH_MILK: + case RG_BOTTLE_WITH_RED_POTION: + case RG_BOTTLE_WITH_GREEN_POTION: + case RG_BOTTLE_WITH_BLUE_POTION: + case RG_BOTTLE_WITH_FAIRY: + case RG_BOTTLE_WITH_FISH: + case RG_BOTTLE_WITH_BLUE_FIRE: + case RG_BOTTLE_WITH_BUGS: + case RG_BOTTLE_WITH_POE: + case RG_BOTTLE_WITH_BIG_POE: + { + uint8_t slot = SLOT_BOTTLE_1; + while (slot != SLOT_BOTTLE_4) { + if (mSaveContext->inventory.items[slot] == ITEM_NONE) { + break; + } + slot++; + } + mSaveContext->inventory.items[slot] = item.GetGIEntry()->itemId; + } break; + case RG_RUTOS_LETTER: + SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state); + break; + case RG_GOHMA_SOUL: + case RG_KING_DODONGO_SOUL: + case RG_BARINADE_SOUL: + case RG_PHANTOM_GANON_SOUL: + case RG_VOLVAGIA_SOUL: + case RG_MORPHA_SOUL: + case RG_BONGO_BONGO_SOUL: + case RG_TWINROVA_SOUL: + case RG_GANON_SOUL: + case RG_OCARINA_A_BUTTON: + case RG_OCARINA_C_UP_BUTTON: + case RG_OCARINA_C_DOWN_BUTTON: + case RG_OCARINA_C_LEFT_BUTTON: + case RG_OCARINA_C_RIGHT_BUTTON: + case RG_GREG_RUPEE: + case RG_FISHING_POLE: + SetRandoInf(RandoGetToRandInf.at(randoGet), state); + break; + case RG_TRIFORCE_PIECE: + mSaveContext->triforcePiecesCollected += (!state ? -1 : 1); + break; + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + break; + } + } + break; + case ITEMTYPE_EQUIP: + { + RandomizerGet itemRG = item.GetRandomizerGet(); + if (itemRG == RG_GIANTS_KNIFE) { + return; + } + uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second; + if (!state) { + mSaveContext->inventory.equipment &= ~equipId; + if (equipId == EQUIP_FLAG_SWORD_BGS) { + mSaveContext->bgsFlag = false; + } + } + else { + mSaveContext->inventory.equipment |= equipId; + if (equipId == EQUIP_FLAG_SWORD_BGS) { + mSaveContext->bgsFlag = true; + } + } + } + break; + case ITEMTYPE_DUNGEONREWARD: + case ITEMTYPE_SONG: + SetQuestItem(RandoGetToQuestItem.find(item.GetRandomizerGet())->second, state); + break; + case ITEMTYPE_MAP: + SetDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); + break; + case ITEMTYPE_COMPASS: + SetDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); + break; + case ITEMTYPE_BOSSKEY: + SetDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); + break; + case ITEMTYPE_FORTRESS_SMALLKEY: + case ITEMTYPE_SMALLKEY: + { + auto randoGet = item.GetRandomizerGet(); + auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; + auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; + auto count = GetSmallKeyCount(dungeonIndex); + if (!state) { + if (keyring) { + count = 0; + } + else { + count -= 1; + } + } + else { + if (keyring) { + count = 10; + } + else { + count += 1; + } + } + SetSmallKeyCount(dungeonIndex, count); + } break; + case ITEMTYPE_TOKEN: + mSaveContext->inventory.gsTokens += (!state ? -1 : 1); + break; + case ITEMTYPE_EVENT: + break; + case ITEMTYPE_DROP: + case ITEMTYPE_REFILL: + case ITEMTYPE_SHOP: + { + RandomizerGet itemRG = item.GetRandomizerGet(); + if (itemRG == RG_BUY_HYLIAN_SHIELD || itemRG == RG_BUY_DEKU_SHIELD || itemRG == RG_BUY_GORON_TUNIC || itemRG == RG_BUY_ZORA_TUNIC) { + uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second; + if (!state) { + mSaveContext->inventory.equipment &= ~equipId; + } + else { + mSaveContext->inventory.equipment |= equipId; + } + } + switch (itemRG) { + case RG_DEKU_NUTS_5: + case RG_DEKU_NUTS_10: + case RG_BUY_DEKU_NUTS_5: + case RG_BUY_DEKU_NUTS_10: + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + break; + case RG_DEKU_STICK_1: + case RG_BUY_DEKU_STICK_1: + case RG_STICKS: + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); + break; + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + break; + } + } break; + } + } + + SaveContext* Logic::GetSaveContext() { + if (mSaveContext == nullptr) { + NewSaveContext(); + } + return mSaveContext; + } + + void Logic::SetSaveContext(SaveContext* context) { + mSaveContext = context; + } + + void Logic::InitSaveContext() { + mSaveContext->totalDays = 0; + mSaveContext->bgsDayCount = 0; + + mSaveContext->deaths = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->playerName); i++) { + mSaveContext->playerName[i] = 0x3E; + } + mSaveContext->n64ddFlag = 0; + mSaveContext->healthCapacity = 0x30; + mSaveContext->health = 0x30; + mSaveContext->magicLevel = 0; + mSaveContext->magic = 0x30; + mSaveContext->rupees = 0; + mSaveContext->swordHealth = 0; + mSaveContext->naviTimer = 0; + mSaveContext->isMagicAcquired = 0; + mSaveContext->isDoubleMagicAcquired = 0; + mSaveContext->isDoubleDefenseAcquired = 0; + mSaveContext->bgsFlag = 0; + mSaveContext->ocarinaGameRoundNum = 0; + for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.buttonItems); button++) { + mSaveContext->childEquips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.cButtonSlots); button++) { + mSaveContext->childEquips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->childEquips.equipment = 0; + for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.buttonItems); button++) { + mSaveContext->adultEquips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.cButtonSlots); button++) { + mSaveContext->adultEquips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->adultEquips.equipment = 0; + mSaveContext->unk_54 = 0; + mSaveContext->savedSceneNum = SCENE_LINKS_HOUSE; + + // Equipment + for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.buttonItems); button++) { + mSaveContext->equips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.cButtonSlots); button++) { + mSaveContext->equips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->equips.equipment = 0; + + // Inventory + for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) { + mSaveContext->inventory.items[item] = ITEM_NONE; + } + for (int ammo = 0; ammo < ARRAY_COUNT(mSaveContext->inventory.ammo); ammo++) { + mSaveContext->inventory.ammo[ammo] = 0; + } + mSaveContext->inventory.equipment = 0; + mSaveContext->inventory.upgrades = 0; + mSaveContext->inventory.questItems = 0; + for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) { + mSaveContext->inventory.dungeonItems[dungeon] = 0; + } + for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) { + mSaveContext->inventory.dungeonKeys[dungeon] = 0x0; + } + mSaveContext->inventory.defenseHearts = 0; + mSaveContext->inventory.gsTokens = 0; + for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) { + mSaveContext->sceneFlags[scene].chest = 0; + mSaveContext->sceneFlags[scene].swch = 0; + mSaveContext->sceneFlags[scene].clear = 0; + mSaveContext->sceneFlags[scene].collect = 0; + mSaveContext->sceneFlags[scene].unk = 0; + mSaveContext->sceneFlags[scene].rooms = 0; + mSaveContext->sceneFlags[scene].floors = 0; + } + mSaveContext->fw.pos.x = 0; + mSaveContext->fw.pos.y = 0; + mSaveContext->fw.pos.z = 0; + mSaveContext->fw.yaw = 0; + mSaveContext->fw.playerParams = 0; + mSaveContext->fw.entranceIndex = 0; + mSaveContext->fw.roomIndex = 0; + mSaveContext->fw.set = 0; + mSaveContext->fw.tempSwchFlags = 0; + mSaveContext->fw.tempCollectFlags = 0; + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->gsFlags); flag++) { + mSaveContext->gsFlags[flag] = 0; + } + for (int highscore = 0; highscore < ARRAY_COUNT(mSaveContext->highScores); highscore++) { + mSaveContext->highScores[highscore] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->eventChkInf); flag++) { + mSaveContext->eventChkInf[flag] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->itemGetInf); flag++) { + mSaveContext->itemGetInf[flag] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->infTable); flag++) { + mSaveContext->infTable[flag] = 0; + } + mSaveContext->worldMapAreaData = 0; + mSaveContext->scarecrowLongSongSet = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowLongSong); i++) { + mSaveContext->scarecrowLongSong[i].noteIdx = 0; + mSaveContext->scarecrowLongSong[i].unk_01 = 0; + mSaveContext->scarecrowLongSong[i].unk_02 = 0; + mSaveContext->scarecrowLongSong[i].volume = 0; + mSaveContext->scarecrowLongSong[i].vibrato = 0; + mSaveContext->scarecrowLongSong[i].tone = 0; + mSaveContext->scarecrowLongSong[i].semitone = 0; + } + mSaveContext->scarecrowSpawnSongSet = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowSpawnSong); i++) { + mSaveContext->scarecrowSpawnSong[i].noteIdx = 0; + mSaveContext->scarecrowSpawnSong[i].unk_01 = 0; + mSaveContext->scarecrowSpawnSong[i].unk_02 = 0; + mSaveContext->scarecrowSpawnSong[i].volume = 0; + mSaveContext->scarecrowSpawnSong[i].vibrato = 0; + mSaveContext->scarecrowSpawnSong[i].tone = 0; + mSaveContext->scarecrowSpawnSong[i].semitone = 0; + } + + mSaveContext->horseData.scene = SCENE_HYRULE_FIELD; + mSaveContext->horseData.pos.x = -1840; + mSaveContext->horseData.pos.y = 72; + mSaveContext->horseData.pos.z = 5497; + mSaveContext->horseData.angle = -0x6AD9; + mSaveContext->magicLevel = 0; + mSaveContext->infTable[29] = 1; + mSaveContext->sceneFlags[5].swch = 0x40000000; + + // SoH specific + mSaveContext->backupFW = mSaveContext->fw; + mSaveContext->pendingSale = ITEM_NONE; + mSaveContext->pendingSaleMod = MOD_NONE; + mSaveContext->isBossRushPaused = 0; + mSaveContext->pendingIceTrapCount = 0; + + // Init with normal quest unless only an MQ rom is provided + mSaveContext->questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER; + + //RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT) + } + + void Logic::NewSaveContext() { + if (mSaveContext != nullptr && mSaveContext != &gSaveContext) { + free(mSaveContext); + } + mSaveContext = new SaveContext(); + InitSaveContext(); + } + + uint8_t Logic::InventorySlot(uint32_t item) { + return gItemSlots[item]; + } + + uint32_t Logic::CurrentUpgrade(uint32_t upgrade) { + return (mSaveContext->inventory.upgrades & gUpgradeMasks[upgrade]) >> gUpgradeShifts[upgrade]; + } + + uint32_t Logic::CurrentInventory(uint32_t item) { + return mSaveContext->inventory.items[InventorySlot(item)]; + } + + void Logic::SetUpgrade(uint32_t upgrade, uint8_t level) { + mSaveContext->inventory.upgrades &= gUpgradeNegMasks[upgrade]; + mSaveContext->inventory.upgrades |= level << gUpgradeShifts[upgrade]; + } + + bool Logic::CheckInventory(uint32_t item, bool exact) { + auto current = mSaveContext->inventory.items[InventorySlot(item)]; + return exact ? (current == item) : (current != ITEM_NONE); + } + + void Logic::SetInventory(uint32_t itemSlot, uint32_t item) { + mSaveContext->inventory.items[InventorySlot(itemSlot)] = item; + } + + bool Logic::CheckEquipment(uint32_t equipFlag) { + return (equipFlag & mSaveContext->inventory.equipment); + } + + bool Logic::CheckQuestItem(uint32_t item) { + return ((1 << item) & mSaveContext->inventory.questItems); + } + + bool Logic::HasAdultTrade(uint32_t itemID) { + int tradeIndex = itemID - ITEM_POCKET_EGG; + return mSaveContext->adultTradeItems & (1 << tradeIndex); + } + + void Logic::SetAdultTrade(uint32_t itemID, bool state) { + int tradeIndex = itemID - ITEM_POCKET_EGG; + if (!state) { + mSaveContext->adultTradeItems &= ~(1 << tradeIndex); + } + else { + mSaveContext->adultTradeItems |= (1 << tradeIndex); + } + } + + void Logic::SetQuestItem(uint32_t item, bool state) { + if (!state) { + mSaveContext->inventory.questItems &= ~(1 << item); + } + else { + mSaveContext->inventory.questItems |= (1 << item); + } + } + + uint8_t Logic::GetSmallKeyCount(uint32_t dungeonIndex) { + return mSaveContext->inventory.dungeonKeys[dungeonIndex]; + } + + void Logic::SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count) { + mSaveContext->inventory.dungeonKeys[dungeonIndex] = count; + } + + bool Logic::CheckDungeonItem(uint32_t item, uint32_t dungeonIndex) { + return mSaveContext->inventory.dungeonItems[dungeonIndex] & gBitFlags[item]; + } + + void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { + if (!state) { + mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; + } + else { + mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; + } + } + + bool Logic::CheckRandoInf(uint32_t flag) { + return mSaveContext->randomizerInf[flag >> 4] & (1 << (flag & 0xF)); + } + + void Logic::SetRandoInf(uint32_t flag, bool state) { + if (!state) { + mSaveContext->randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); + } + else { + mSaveContext->randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); + } + } + + bool Logic::CheckEventChkInf(int32_t flag) { + return mSaveContext->eventChkInf[flag >> 4] & (1 << (flag & 0xF)); + } + + void Logic::SetEventChkInf(int32_t flag, bool state) { + if (!state) { + mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); + } + else { + mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); + } + } + + uint8_t Logic::GetGSCount() { + return mSaveContext->inventory.gsTokens; + } + + uint8_t Logic::GetAmmo(uint32_t item) { + return mSaveContext->inventory.ammo[gItemSlots[item]]; + } + + void Logic::SetAmmo(uint32_t item, uint8_t count) { + mSaveContext->inventory.ammo[gItemSlots[item]] = count; } void Logic::SetContext(std::shared_ptr _ctx) { @@ -772,7 +1580,8 @@ namespace Rando { } void Logic::Reset() { - ctx->NewSaveContext(); + NewSaveContext(); + StartPerformanceTimer(PT_LOGIC_RESET); memset(inLogic, false, sizeof(inLogic)); //Settings-dependent variables IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || @@ -781,48 +1590,12 @@ namespace Rando { AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE) TODO: AmmoDrop setting*/ true; //Child item logic - KokiriSword = false; - ZeldasLetter = false; - WeirdEgg = false; - HasBottle = false; - MagicBean = false; - RutosLetter = false; - Boomerang = false; - DinsFire = false; - FaroresWind = false; - NayrusLove = false; - LensOfTruth = false; - ShardOfAgony = false; SkullMask = false; MaskOfTruth = false; //Adult logic - Hammer = false; - IronBoots = false; - HoverBoots = false; - MirrorShield = false; - GoronTunic = false; - ZoraTunic = false; - Epona = false; + FreedEpona = false; //BigPoe = false; - GerudoToken = false; - FireArrows = false; - IceArrows = false; - LightArrows = false; - MasterSword = false; - BiggoronSword = false; - - //Trade Quest - PocketEgg = false; - Cojiro = false; - OddMushroom = false; - OddPoultice = false; - PoachersSaw = false; - BrokenSword = false; - Prescription = false; - EyeballFrog = false; - Eyedrops = false; - ClaimCheck = false; //Trade Quest Events WakeUpAdultTalon = false; @@ -836,17 +1609,6 @@ namespace Rando { EyedropsAccess = false; DisableTradeRevert = false; - //Stones and Meddallions - ForestMedallion = false; - FireMedallion = false; - WaterMedallion = false; - SpiritMedallion = false; - ShadowMedallion = false; - LightMedallion = false; - KokiriEmerald = false; - GoronRuby = false; - ZoraSapphire = false; - //Dungeon Clears DekuTreeClear = false; DodongosCavernClear = false; @@ -865,77 +1627,42 @@ namespace Rando { ShadowTrialClear = false; LightTrialClear = false; - //Greg - Greg = false; - GregInBridgeLogic = false; - GregInLacsLogic = false; - //Ocarina C Buttons bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true); - ctx->SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle); - ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle); - ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle); - ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle); - ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle); //Progressive Items - ctx->SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1); - ctx->SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1); - ProgressiveBulletBag = 0; - ProgressiveBombBag = 0; - ProgressiveMagic = 0; - //If we're not shuffling swim, we start with it (scale 1) - ProgressiveScale = 0; + SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1); + SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1); + + //If we're not shuffling swim, we start with it if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) { - ProgressiveScale = 1; - ctx->SetRandoInf(RAND_INF_CAN_SWIM, true); + SetRandoInf(RAND_INF_CAN_SWIM, true); } - ProgressiveHookshot = 0; - ProgressiveBow = 0; - //If we're not shuffling child's wallet, we start with it (wallet 1) - ProgressiveWallet = 0; + + //If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { - ProgressiveWallet = 1; - ctx->SetRandoInf(RAND_INF_HAS_WALLET, true); + SetRandoInf(RAND_INF_HAS_WALLET, true); + } + + //If we're not shuffling fishing pole, we start with it + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE).Is(false)) { + SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true); } - ProgressiveStrength = 0; - ProgressiveOcarina = 0; - ProgressiveGiantKnife = 0; //If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla FiT if (!IsKeysanity && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { - ctx->SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1); + SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1); } - //Boss Keys - BossKeyForestTemple = 0; - BossKeyFireTemple = 0; - BossKeyWaterTemple = 0; - BossKeySpiritTemple = 0; - BossKeyShadowTemple = 0; - BossKeyGanonsCastle = 0; - - //Gold Skulltula Count - GoldSkulltulaTokens = 0; - //Bottle Count Bottles = 0; NumBottles = 0; - NoBottles = false; - - //Triforce Pieces - TriforcePieces = 0; - - //Boss Souls - CanSummonGohma = false; - CanSummonKingDodongo = false; - CanSummonBarinade = false; - CanSummonPhantomGanon = false; - CanSummonVolvagia = false; - CanSummonMorpha = false; - CanSummonBongoBongo = false; - CanSummonTwinrova = false; - CanSummonGanon = false; + CanEmptyBigPoes = true; //Drops and Bottle Contents Access NutPot = false; @@ -955,122 +1682,33 @@ namespace Rando { FairyPot = false; FreeFairies = false; FairyPond = false; - BombchuRefill = false; - BombchusEnabled = false; - BuyBombchus = false; - - BuySeed = false; - BuyArrow = false; - BuyBomb = false; - BuyMagicPotion = false; - BuyFish = false; - BuyBugs = false; - BuyFairy = false; PieceOfHeart = 0; HeartContainer = 0; - DoubleDefense = false; /* --- 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. */ - BulletBag = false; - Slingshot = false; - Ocarina = false; - OcarinaOfTime = false; - BombBag = false; - MagicMeter = false; - Hookshot = false; - Longshot = false; - Quiver = false; - Bow = false; - GoronBracelet = false; - SilverGauntlets = false; - GoldenGauntlets = false; - Swim = false; - SilverScale = false; - GoldScale = false; - ChildsWallet = false; - AdultsWallet = false; - ChildScarecrow = false; AdultScarecrow = false; - ScarecrowSong = false; - Scarecrow = false; - DistantScarecrow = false; - - Bombs = false; - DekuShield = false; - HylianShield = false; - BlueFire = false; - BottleWithBigPoe = false; - - CouldPlayBowling = false; - HasExplosives = false; - HasBoots = false; + + CouldPlayBowling = false; IsChild = false; IsAdult = false; - IsGlitched = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED); - CanBlastOrSmash = false; - CanChildAttack = false; - CanChildDamage = false; - CanCutShrubs = false; - CanDive = false; - CanLeaveForest = false; - CanPlantBugs = false; - CanRideEpona = false; - CanStunDeku = false; - CanSummonGossipFairy = false; - CanSummonGossipFairyWithoutSuns = false; //CanPlantBean = false; - CanOpenBombGrotto = false; - CanOpenStormGrotto = false; BigPoeKill = false; - HookshotOrBoomerang = false; - CanBreakUpperBeehives = false; - CanBreakLowerBeehives = false; - CanGetChildFish = false; - CanGetAdultFish = false; - FishingPole = false; - CanFish = false; BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Value() + 1; - Hearts = 0; - Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() : 10; - EffectiveHealth = 0; - FireTimer = 0; - WaterTimer = 0; - - GuaranteeTradePath = false; - GuaranteeHint = false; - HasFireSource = false; - HasFireSourceWithTorch = false; - - CanFinishGerudoFortress = false; - - HasShield = false; - CanShield = false; - ChildShield = false; - AdultReflectShield = false; - AdultShield = false; - CanShieldFlick = false; - CanJumpslash = false; - CanUseProjectile = false; - CanUseMagicArrow = false; + //Bridge Requirements - HasAllStones = false; - HasAllMedallions = false; - CanBuildRainbowBridge = false; BuiltRainbowBridge = false; - CanTriggerLACS = false; //Other AtDay = false; AtNight = false; - Age = ctx->GetSettings()->ResolvedStartingAge(); - ctx->GetSaveContext()->linkAge = !Age; + GetSaveContext()->linkAge = !ctx->GetSettings()->ResolvedStartingAge(); //Events ShowedMidoSwordAndShield = false; @@ -1096,22 +1734,8 @@ namespace Rando { ForestTempleAmyAndMeg = false; FireLoopSwitch = false; LinksCow = false; - AtDampeTime = false; DeliverLetter = false; - TimeTravel = false; - - DrainWellPast = false; - DampesWindmillAccessPast = false; - DekuTreeClearPast = false; - GoronRubyPast = false; - ZoraSapphirePast = false; - ForestTrialClearPast = false; - FireTrialClearPast = false; - WaterTrialClearPast = false; - SpiritTrialClearPast = false; - ShadowTrialClearPast = false; - LightTrialClearPast = false; - BuyDekuShieldPast = false; - TimeTravelPast = false; + + StopPerformanceTimer(PT_LOGIC_RESET); } } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 6a669d7ebb0..dee521425e3 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -31,49 +31,12 @@ class Logic { bool noVariable = false; // Child item logic - bool KokiriSword = false; - bool BulletBag = false; - bool ZeldasLetter = false; - bool WeirdEgg = false; - bool HasBottle = false; - bool MagicBean = false; - bool RutosLetter = false; - bool Boomerang = false; - bool DinsFire = false; - bool FaroresWind = false; - bool NayrusLove = false; - bool LensOfTruth = false; - bool ShardOfAgony = false; bool SkullMask = false; bool MaskOfTruth = false; // Adult logic - bool Hammer = false; - bool IronBoots = false; - bool HoverBoots = false; - bool MirrorShield = false; - bool GoronTunic = false; - bool ZoraTunic = false; - bool Epona = false; + bool FreedEpona = false; //bool BigPoe = false; //unused - bool GerudoToken = false; - bool FireArrows = false; - bool IceArrows = false; - bool LightArrows = false; - bool MasterSword = false; - bool BiggoronSword = false; - - // Trade Quest - bool PocketEgg = false; - bool Cojiro = false; - bool OddMushroom = false; - bool OddPoultice = false; - bool PoachersSaw = false; - bool BrokenSword = false; - bool Prescription = false; - bool EyeballFrog = false; - bool Eyedrops = false; - bool ClaimCheck = false; // Trade Quest Events bool WakeUpAdultTalon = false; @@ -87,17 +50,6 @@ class Logic { bool EyedropsAccess = false; bool DisableTradeRevert = false; - // Stones and Meddallions - bool ForestMedallion = false; - bool FireMedallion = false; - bool WaterMedallion = false; - bool SpiritMedallion = false; - bool ShadowMedallion = false; - bool LightMedallion = false; - bool KokiriEmerald = false; - bool GoronRuby = false; - bool ZoraSapphire = false; - // Dungeon Clears bool DekuTreeClear = false; bool DodongosCavernClear = false; @@ -116,56 +68,13 @@ class Logic { bool ShadowTrialClear = false; bool LightTrialClear = false; - // Greg - bool Greg = false; - bool GregInBridgeLogic = false; - bool GregInLacsLogic = false; - - // Progressive Items - uint8_t ProgressiveBulletBag = 0; - uint8_t ProgressiveBombBag = 0; - uint8_t ProgressiveMagic = 0; - uint8_t ProgressiveScale = 0; - uint8_t ProgressiveHookshot = 0; - uint8_t ProgressiveBow = 0; - uint8_t ProgressiveWallet = 0; - uint8_t ProgressiveStrength = 0; - uint8_t ProgressiveOcarina = 0; - uint8_t ProgressiveGiantKnife = 0; - // Logical keysanity bool IsKeysanity = false; - // Keys - uint8_t ForestTempleKeys = 0; - uint8_t FireTempleKeys = 0; - uint8_t WaterTempleKeys = 0; - uint8_t SpiritTempleKeys = 0; - uint8_t ShadowTempleKeys = 0; - uint8_t GanonsCastleKeys = 0; - uint8_t GerudoFortressKeys = 0; - uint8_t GerudoTrainingGroundsKeys = 0; - uint8_t BottomOfTheWellKeys = 0; - uint8_t TreasureGameKeys = 0; - - // Triforce Pieces - uint8_t TriforcePieces = 0; - - // Boss Keys - bool BossKeyForestTemple = false; - bool BossKeyFireTemple = false; - bool BossKeyWaterTemple = false; - bool BossKeySpiritTemple = false; - bool BossKeyShadowTemple = false; - bool BossKeyGanonsCastle = false; - - // Gold Skulltula Count - uint8_t GoldSkulltulaTokens = 0; - // Bottle Count uint8_t Bottles = 0; uint8_t NumBottles = 0; - bool NoBottles = false; + bool CanEmptyBigPoes = true; // Drops and Bottle Contents Access bool NutPot = false; @@ -186,149 +95,26 @@ class Logic { bool FreeFairies = false; bool FairyPond = false; bool AmmoCanDrop = false; - bool BombchuRefill = false; - bool BombchusEnabled = false; - bool BuyBombchus = false; - - bool BuySeed = false; - bool BuyArrow = false; - bool BuyBomb = false; - bool BuyMagicPotion = false; - bool BuyFish = false; - bool BuyBugs = false; - bool BuyFairy = false; uint8_t PieceOfHeart = 0; uint8_t HeartContainer = 0; - bool DoubleDefense = false; - - /* --- 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. */ - - bool Ocarina = false; - bool OcarinaOfTime = false; - bool BombBag = false; - bool MagicMeter = false; - bool Hookshot = false; - bool Longshot = false; - bool Quiver = false; - bool GoronBracelet = false; - bool SilverGauntlets = false; - bool GoldenGauntlets = false; - bool Swim = false; - bool SilverScale = false; - bool GoldScale = false; - bool ChildsWallet = false; - bool AdultsWallet = false; bool ChildScarecrow = false; bool AdultScarecrow = false; - bool ScarecrowSong = false; - bool Scarecrow = false; - bool DistantScarecrow = false; - - bool Slingshot = false; - bool Bombs = false; - bool Bow = false; - bool DekuShield = false; - bool HylianShield = false; - bool BlueFire = false; - bool BottleWithBigPoe = false; - - bool OcarinaAButton = false; - bool OcarinaCLeftButton = false; - bool OcarinaCRightButton = false; - bool OcarinaCUpButton = false; - bool OcarinaCDownButton = false; bool CarpetMerchant = false; bool CouldPlayBowling = false; - bool HasExplosives = false; - bool HasBoots = false; bool IsChild = false; bool IsAdult = false; - bool IsGlitched = false; - bool CanBlastOrSmash = false; - bool CanChildAttack = false; - bool CanChildDamage = false; - bool CanAdultAttack = false; - bool CanAdultDamage = false; - bool CanCutShrubs = false; - bool CanDive = false; - bool CanLeaveForest = false; - bool CanPlantBugs = false; - bool CanRideEpona = false; - bool CanStunDeku = false; - bool CanSummonGossipFairy = false; - bool CanSummonGossipFairyWithoutSuns = false; - bool NeedNayrusLove = false; - bool CanSurviveDamage = false; - bool CanTakeDamage = false; - bool CanTakeDamageTwice = false; - // bool CanPlantBean = false; - bool CanOpenBombGrotto = false; - bool CanOpenStormGrotto = false; bool BigPoeKill = false; - bool HookshotOrBoomerang = false; - bool CanGetNightTimeGS = false; - bool CanBreakLowerBeehives = false; - bool CanBreakUpperBeehives = false; - bool FishingPole = false; - bool CanGetChildFish = false; - bool CanGetAdultFish = false; - bool CanFish = false; - - uint8_t OcarinaButtons = 0; uint8_t BaseHearts = 0; - uint8_t Hearts = 0; - uint8_t Multiplier = 0; - uint8_t EffectiveHealth = 0; - uint8_t FireTimer = 0; - uint8_t WaterTimer = 0; - - bool GuaranteeTradePath = false; - bool GuaranteeHint = false; - bool HasFireSource = false; - bool HasFireSourceWithTorch = false; - - bool CanFinishGerudoFortress = false; - - bool HasShield = false; - bool CanShield = false; - bool ChildShield = false; - bool AdultReflectShield = false; - bool AdultShield = false; - bool CanShieldFlick = false; - bool CanJumpslash = false; - bool CanUseProjectile = false; - bool CanUseMagicArrow = false; // Bridge and LACS Requirements - uint8_t StoneCount = 0; - uint8_t MedallionCount = 0; - uint8_t DungeonCount = 0; - bool HasAllStones = false; - bool HasAllMedallions = false; - bool CanBuildRainbowBridge = false; bool BuiltRainbowBridge = false; - bool CanTriggerLACS = false; // Other bool AtDay = false; bool AtNight = false; - uint8_t Age = 0; - bool CanCompleteTriforce = false; - - bool CanSummonGohma = false; - bool CanSummonKingDodongo = false; - bool CanSummonBarinade = false; - bool CanSummonPhantomGanon = false; - bool CanSummonVolvagia = false; - bool CanSummonMorpha = false; - bool CanSummonBongoBongo = false; - bool CanSummonTwinrova = false; - bool CanSummonGanon = false; // Events bool ShowedMidoSwordAndShield = false; @@ -354,42 +140,13 @@ class Logic { bool ForestTempleAmyAndMeg = false; bool FireLoopSwitch = false; bool LinksCow = false; - bool AtDampeTime = false; bool DeliverLetter = false; - bool TimeTravel = false; + bool ClearMQDCUpperLobbyRocks = false; /* --- END OF HELPERS AND LOCATION ACCESS --- */ - // Placement Tracking - uint8_t AddedProgressiveBulletBags = 0; - uint8_t AddedProgressiveBombBags = 0; - uint8_t AddedProgressiveMagics = 0; - uint8_t AddedProgressiveScales = 0; - uint8_t AddedProgressiveHookshots = 0; - uint8_t AddedProgressiveBows = 0; - uint8_t AddedProgressiveWallets = 0; - uint8_t AddedProgressiveStrengths = 0; - uint8_t AddedProgressiveOcarinas = 0; - uint8_t TokensInPool = 0; - - // Event checking past - bool DrainWellPast = false; - bool DampesWindmillAccessPast = false; - bool DekuTreeClearPast = false; - bool GoronRubyPast = false; - bool ZoraSapphirePast = false; - bool ForestTrialClearPast = false; - bool FireTrialClearPast = false; - bool WaterTrialClearPast = false; - bool SpiritTrialClearPast = false; - bool ShadowTrialClearPast = false; - bool LightTrialClearPast = false; - bool BuyDekuShieldPast = false; - bool TimeTravelPast = false; - - SaveContext* mSaveContext; + SaveContext* mSaveContext = nullptr; Logic(); - void UpdateHelpers(); bool CanUse(RandomizerGet itemName); bool HasProjectile(HasProjectileAge age); bool HasItem(RandomizerGet itemName); @@ -398,14 +155,90 @@ class Logic { bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); - bool CanKillEnemy(std::string enemy); - bool CanPassEnemy(std::string enemy); - bool EventsUpdated(); + bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE); + bool CanPassEnemy(RandomizerEnemy enemy); + bool CanAvoidEnemy(RandomizerEnemy enemy); + bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false); + bool CanBreakMudWalls(); + bool CanGetDekuBabaSticks(); + bool CanHitEyeTargets(); + bool CanDetonateBombFlowers(); + bool CanDetonateUprightBombFlower(); uint8_t BottleCount(); + uint8_t OcarinaButtons(); + bool HasBottle(); + bool CanJumpslash(); + bool CanDamage(); + bool CanAttack(); + bool BombchusEnabled(); + bool BombchuRefill(); + bool HookshotOrBoomerang(); + bool ScarecrowsSong(); + bool BlueFire(); + bool HasExplosives(); + bool BlastOrSmash(); + bool CanSpawnSoilSkull(); + bool CanReflectNuts(); + bool CanCutShrubs(); + bool CanStunDeku(); + bool CanLeaveForest(); + bool CallGossipFairy(); + bool CallGossipFairyExceptSuns(); + uint8_t EffectiveHealth(); + uint8_t Hearts(); + uint8_t StoneCount(); + uint8_t MedallionCount(); + uint8_t DungeonCount(); + uint8_t FireTimer(); + uint8_t WaterTimer(); + bool TakeDamage(); + bool CanOpenBombGrotto(); + bool CanOpenStormsGrotto(); + bool CanGetNightTimeGS(); + bool CanBreakUpperBeehives(); + bool CanBreakLowerBeehives(); + bool HasFireSource(); + bool HasFireSourceWithTorch(); + bool CanFinishGerudoFortress(); + bool CanShield(); + bool CanUseProjectile(); + bool CanBuildRainbowBridge(); + bool CanTriggerLACS(); void Reset(); void SetContext(std::shared_ptr _ctx); bool GetInLogic(LogicVal logicVal); void SetInLogic(LogicVal logicVal, bool remove); + void ApplyItemEffect(Item& item, bool state); + uint8_t InventorySlot(uint32_t item); + void SetUpgrade(uint32_t upgrade, uint8_t level); + uint32_t CurrentUpgrade(uint32_t upgrade); + uint32_t CurrentInventory(uint32_t item); + bool CheckInventory(uint32_t item, bool exact); + void SetInventory(uint32_t itemSlot, uint32_t item); + bool CheckEquipment(uint32_t item); + bool CheckQuestItem(uint32_t item); + void SetQuestItem(uint32_t item, bool state); + bool HasAdultTrade(uint32_t item); + void SetAdultTrade(uint32_t item, bool state); + uint8_t GetSmallKeyCount(uint32_t dungeonIndex); + void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count); + bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex); + void SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state); + bool CheckRandoInf(uint32_t flag); + void SetRandoInf(uint32_t flag, bool state); + bool CheckEventChkInf(int32_t flag); + uint8_t GetGSCount(); + void SetEventChkInf(int32_t flag, bool state); + uint8_t GetAmmo(uint32_t item); + void SetAmmo(uint32_t item, uint8_t count); + SaveContext* GetSaveContext(); + void SetSaveContext(SaveContext* context); + void InitSaveContext(); + void NewSaveContext(); + static std::map RandoGetToQuestItem; + static std::map RandoGetToDungeonScene; + static std::map RandoGetToEquipFlag; + static std::map RandoGetToRandInf; private: static bool IsMagicItem(RandomizerGet item); diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index 36fdd1f8ba4..9a597726214 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -240,7 +240,7 @@ bool Option::RenderCombobox() const { ImGui::Text("%s", name.c_str()); uint8_t selected = CVarGetInteger(cvarName.c_str(), defaultOption); if (selected >= options.size()) { - selected--; + selected = options.size(); CVarSetInteger(cvarName.c_str(), selected); changed = true; Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); @@ -272,7 +272,8 @@ bool Option::RenderSlider() const { bool changed = false; int val = CVarGetInteger(cvarName.c_str(), defaultOption); if (val >= options.size()) { - val--; + val = options.size(); + CVarSetInteger(cvarName.c_str(), val); changed = true; } if (disabled) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 597b46db605..547d675df66 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -263,13 +263,19 @@ void Settings::CreateOptionDescriptions() { "The deku nut bag is required to hold deku nuts."; mOptionDescriptions[RSK_SHOPSANITY] = "Off - All shop items will be the same as vanilla.\n" "\n" - "0 Items - Vanilla shop items will be shuffled among different shops.\n" - "\n" - "1-4 Items - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain 1-4 non-vanilla shop items.\n" + "Specifc Count - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain a specifc number (0-7) of non-vanilla shop items.\n" "\n" "Random - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain a random number(1-4) of non-vanilla shop items.\n"; + "each shop will contain a random number (1-7) of non-vanilla shop items."; + mOptionDescriptions[RSK_SHOPSANITY_COUNT] = "0 Items - Vanilla shop items will be shuffled among different shops.\n" + "\n" + "1-7 Items - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain 1-7 non-vanilla shop items.\n" + /* + "\n" + "8 Items - All shops will contain 8 non-vanilla shop items.\n" + */; mOptionDescriptions[RSK_SHOPSANITY_PRICES] = "Balanced - The default randomization. Shop prices for shopsanity items will range between 0 to 300 rupees, " "with a bias towards values slightly below the middle of the range, in multiples of 5.\n " diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 066faca7eed..45c794244b7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -56,8 +56,6 @@ std::set spoilerExcludedLocations; std::set enabledTricks; std::set enabledGlitches; -std::set> checkTrackerStates; - u8 generated; char* seedString; @@ -70,61 +68,69 @@ const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi"; const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; -static const char* englishRupeeNames[171] = { - "[P]", "Bad RNG Rolls", "Bananas", "Beanbean Coins", "Beans", - "Beli", "Bells", "Berries", "Bison Dollars", "Bitcoin", - "Blue Essence", "Bolts", "Bones", "Boondollars", "Bottle Caps", - "Bratwürste", "Bucks", "BugFrags", "Canadian Dollars", "Cards", - "Chaos Orbs", "Clams", "Coal", "Cocoa Beans", "Coins", - "Cookies", "Copper", "Cor", "Cornflakes", "Credits", - "Crimebucks", "Crystal Shards", "Cubits", "Cucumbers", "Dalmations", - "Dampécoin", "Dark Elixir", "Darseks", "Dead Memes", "Diamonds", - "DNA", "Doge", "Dogecoin", "Doll Hairs", "Dollars", - "Dollarydoos", "Dosh", "Doubloons", "Dwarfbucks", "Emeralds", - "Energon", "Eris", "Ether", "Euro", "Experience", - "Extinction Points", "Floopies", "Flurbos", "FPS", "Friends", - "Frog Coins", "Gald", "Gekz", "Gems", "Geo", - "Gil", "Glimmer", "Glitches", "Gold", "Gold Dragons", - "Goober Dollars", "Green Herbs", "Greg Siblings", "Gummybears", "Hell", - "Hyrule Loaches", "Ice Traps", "ISK", "Jiggies", "KF7 Ammo", - "Kinstones", "Kremcoins", "Kroner", "Leaves ", "Lemmings", - "Lien", "Lira", "Lumber", "Lungmen Dollars", "Macca", - "Mana", "Mann Co. Keys", "Meat", "Meat Stacks", "Medaparts", - "Meseta", "Mesetas", "Minerals", "Monopoly Money", "Moons", - "Mora", "Mumbo Tokens", "Munny", "Mushrooms", "Mysteries", - "Neopoints", "Notes", "Nuyen", "Orbs", "Pix", - "Pixels", "Platinum", "Pokédollars", "Pokémon", "Poko", - "Pokos", "Potch", "Pounds", "Power Pellets", "Primogems", - "Réals", "Refined Metal", "Remote Mines", "Retweets", "Rhinu", - "Rings", "Riot Points", "Robux", "Rubies", "Rubles", - "Runite Ore", "Rupees", "Saint Quartz", "Septims", "Shekels", - "Shillings", "Silver", "Simoleons", "Smackaroos", "Social Credit", - "Souls", "Spent Casings", "Spice", "Spondulicks", "Spoons", - "Star Bits", "Star Chips", "Stars", "Stones of Jordan", "Store Credit", - "Strawbs", "Studs", "Super Sea Snails", "Talent", "Teef", - "Telecrystals", "Tiberium", "TokKul", "Toys", "Turnips", - "Upvotes", "V-Bucks", "Vespene Gas", "Watts", "Widgets", - "Woolongs", "World Dollars", "Wumpa Fruit", "Yen", "Zenny", - "Zorkmids" +static const char* englishRupeeNames[175] = { + "[P]", "Bad RNG Rolls", "Bananas", "Beanbean Coins", "Beans", + "Beli", "Bells", "Berries", "Bison Dollars", "Bitcoin", + "Blue Essence", "Bolts", "Bones", "Boondollars", "Bottle Caps", + "Bratwürste", "Bucks", "BugFrags", "Canadian Dollars", "Cards", + "Chaos Orbs", "Clams", "Coal", "Cocoa Beans", "Coins", + "Cookies", "Copper", "Cor", "Cornflakes", "Credits", + "Crimebucks", "Crystal Shards", "Cubits", "Cucumbers", "Dalmations", + "Dampécoin", "Dark Elixir", "Darseks", "Dead Memes", "Diamonds", + "DNA", "Doge", "Dogecoin", "Doll Hairs", "Dollars", + "Dollarydoos", "Dosh", "Doubloons", "Dwarfbucks", "Elexit", + "Emeralds", "Energon", "Eris", "Ether", "Euro", + "Experience", "Extinction Points", "Floopies", "Flurbos", "FPS", + "Friends", "Frog Coins", "Gald", "Gekz", "Gems", + "Geo", "Gil", "Glimmer", "Glitches", "Gold", + "Gold Dragons", "Goober Dollars", "Green Herbs", "Greg Siblings", "Grouses", + "Gummybears", "Hell", "Hyrule Loaches", "Ice Traps", "ISK", + "Jiggies", "KF7 Ammo", "Kinstones", "Kremcoins", "Kroner", + "Leaves", "Lemmings", "Lien", "Lira", "Lumber", + "Lungmen Dollars", "Macca", "Mana", "Mann Co. Keys", "Meat", + "Meat Stacks", "Medaparts", "Meseta", "Mesetas", "Minerals", + "Monopoly Money", "Moons", "Mora", "Mumbo Tokens", "Munny", + "Mushrooms", "Mysteries", "Neopoints", "Notes", "Nuyen", + "Orbs", "Ore", "Pix", "Pixels", "Plastyks", + "Platinum", "Pokédollars", "Pokémon", "Poko", "Pokos", + "Potch", "Pounds", "Power Pellets", "Primogems", "Réals", + "Refined Metal", "Remote Mines", "Retweets", "Rhinu", "Rings", + "Riot Points", "Robux", "Rubies", "Rubles", "Runite Ore", + "Rupees", "Saint Quartz", "Septims", "Shekels", "Shillings", + "Silver", "Simoleons", "Smackaroos", "Social Credit", "Souls", + "Spent Casings", "Spice", "Spondulicks", "Spoons", "Star Bits", + "Star Chips", "Stars", "Stones of Jordan", "Store Credit", "Strawbs", + "Studs", "Super Sea Snails", "Talent", "Teef", "Telecrystals", + "Tiberium", "TokKul", "Toys", "Turnips", "Upvotes", + "V-Bucks", "Vespene Gas", "Watts", "Widgets", "Woolongs", + "World Dollars", "Wumpa Fruit", "Yen", "Zenny", "Zorkmids" }; -static const char* germanRupeeNames[56] = { - "Rubine", "Mäuse", "Kröten", "Münzen", "Euro", "Mark", "Bananen", - "Gummibären", "Bonbons", "Diamanten", "Bratwürste", "Bitcoin", "Dogecoin", "Monde", - "Sterne", "Brause UFOs", "Taler", "Sternis", "Schilling", "Freunde", "Seelen", - "Gil", "Zenny", "Pfandflaschen", "Knochen", "Pilze", "Smaragde", "Kronkorken", - "Pokédollar", "Brötchen", "EXP", "Wagenchips", "Moos", "Knete", "Kohle", - "Kies", "Radieschen", "Diridari", "Steine", "Kartoffeln", "Penunze", "ECU", - "Franken", "Cent", "Pfennig", "Groschen", "Rappen", "Gulden", "Kreuzer", - "Kronen", "Forint", "Heller", "Pfund", "Karolin", "Pesa", "Tael" +static const char* germanRupeeNames[65] = { + "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", + "Brötchen", "Cent", "Diamanten", "Diridari", "Dogecoin", + "ECU", "Elexit", "Erz", "Erzbrocken", "Euro", + "EXP", "Forint", "Franken", "Freunde", "Gil", + "Gold", "Groschen", "Gulden", "Gummibären", "Heller", + "Juwelen", "Karolin", "Kartoffeln", "Kies", "Knete", + "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", + "Kronkorken", "Kröten", "Mark", "Mäuse", "Monde", + "Moorhühner", "Moos", "Münzen", "Penunze", "Pesa", + "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", + "Pokédollar", "Radieschen", "Rappen", "Rubine", "Saphire", + "Schilling", "Seelen", "Smaragde", "Steine", "Sterne", + "Sternis", "Tael", "Taler", "Wagenchips", "Zenny" }; -static const char* frenchRupeeNames[36] = { - "Rubis", "Bitcoin", "Bananes", "Euros", "Dollars", "Émeraudes", "Joyaux", "Diamants", - "Balles", "Pokémon", "Pièces", "Lunes", "Étoiles", "Dogecoin", "Anneaux", "Radis", - "Pokédollars", "Zennies", "Pépètes", "Mailles", "Éthers", "Clochettes", "Capsules", "Gils", - "Champignons", "Blés", "Halos", "Munnies", "Orens", "Florens", "Crédits", "Galds", - "Bling", "Orbes", "Baguettes", "Croissants" +static const char* frenchRupeeNames[40] = { + "Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", + "Blés", "Bling", "Capsules", "Centimes", "Champignons", + "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", + "Dollars", "Émeraudes", "Éthers", "Étoiles", "Euros", + "Florens", "Francs", "Galds", "Gils", "Grouses", + "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", + "Orbes", "Orens", "Pépètes", "Pièces", "Plastyks", + "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies" }; Randomizer::Randomizer() { @@ -140,7 +146,7 @@ Randomizer::Randomizer() { SpoilerfileAreaNameToEnum["the Graveyard"] = RCAREA_GRAVEYARD; SpoilerfileAreaNameToEnum["Haunted Wasteland"] = RCAREA_WASTELAND; SpoilerfileAreaNameToEnum["outside Ganon's Castle"] = RCAREA_HYRULE_CASTLE; - for (int c = 0; c < Rando::StaticData::hintTypeNames.size(); c++) { + for (size_t c = 0; c < Rando::StaticData::hintTypeNames.size(); c++) { SpoilerfileHintTypeNameToEnum[Rando::StaticData::hintTypeNames[(HintType)c].GetEnglish(MF_CLEAN)] = (HintType)c; } } @@ -361,7 +367,13 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // Shopsanity with at least one item shuffled allows for a third wallet upgrade. // This is needed since Plentiful item pool also adds a third progressive wallet // but we should *not* get Tycoon's Wallet in that mode. - bool tycoonWallet = GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS; + bool tycoonWallet = !( + GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF || + ( + GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT && + GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS + ) + ); // Same thing with the infinite upgrades, if we're not shuffling them // and we're using the Plentiful item pool, we should prevent the infinite @@ -723,520 +735,6 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe } } -GetItemID Randomizer::GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItemID ogItemId) { - // Shopsanity with at least one item shuffled allows for a third wallet upgrade. - // This is needed since Plentiful item pool also adds a third progressive wallet - // but we should *not* get Tycoon's Wallet in that mode. - bool tycoonWallet = GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS; - - // Same thing with the infinite upgrades, if we're not shuffling them - //and we're using the Plentiful item pool, we should prevent the infinite - //upgrades from being gotten - u8 infiniteUpgrades = GetRandoSettingValue(RSK_INFINITE_UPGRADES); - switch (randoGet) { - case RG_NONE: - return ogItemId; - case RG_TRIFORCE: - case RG_HINT: - case RG_MAX: - case RG_SOLD_OUT: - return GI_NONE; - - // Equipment - case RG_KOKIRI_SWORD: - return GI_SWORD_KOKIRI; - case RG_PROGRESSIVE_GORONSWORD: //todo progressive? - return GI_SWORD_BGS; - case RG_GIANTS_KNIFE: - return GI_SWORD_KNIFE; - case RG_BIGGORON_SWORD: - return GI_SWORD_BGS; - case RG_DEKU_SHIELD: - case RG_BUY_DEKU_SHIELD: - return GI_SHIELD_DEKU; - case RG_HYLIAN_SHIELD: - case RG_BUY_HYLIAN_SHIELD: - return GI_SHIELD_HYLIAN; - case RG_MIRROR_SHIELD: - return GI_SHIELD_MIRROR; - case RG_GORON_TUNIC: - case RG_BUY_GORON_TUNIC: - return GI_TUNIC_GORON; - case RG_ZORA_TUNIC: - case RG_BUY_ZORA_TUNIC: - return GI_TUNIC_ZORA; - case RG_IRON_BOOTS: - return GI_BOOTS_IRON; - case RG_HOVER_BOOTS: - return GI_BOOTS_HOVER; - - // Inventory Items - case RG_PROGRESSIVE_STICK_UPGRADE: - switch (CUR_UPG_VALUE(UPG_STICKS)) { - case 0: - case 1: - return GI_STICK_UPGRADE_20; - case 2: - return GI_STICK_UPGRADE_30; - case 3: - case 4: - return infiniteUpgrades == RO_INF_UPGRADES_PROGRESSIVE ? (GetItemID)RG_STICK_UPGRADE_INF : GI_STICK_UPGRADE_30; - } - case RG_PROGRESSIVE_NUT_UPGRADE: - switch (CUR_UPG_VALUE(UPG_NUTS)) { - case 0: - case 1: - return GI_NUT_UPGRADE_30; - case 2: - return GI_NUT_UPGRADE_40; - case 3: - case 4: - return infiniteUpgrades == RO_INF_UPGRADES_PROGRESSIVE ? (GetItemID)RG_NUT_UPGRADE_INF : GI_NUT_UPGRADE_40; - } - case RG_PROGRESSIVE_BOMB_BAG: - switch (CUR_UPG_VALUE(UPG_BOMB_BAG)) { - case 0: - return GI_BOMB_BAG_20; - case 1: - return GI_BOMB_BAG_30; - case 2: - return GI_BOMB_BAG_40; - case 3: - case 4: - return infiniteUpgrades == RO_INF_UPGRADES_PROGRESSIVE ? (GetItemID)RG_BOMB_BAG_INF : GI_BOMB_BAG_40; - } - case RG_BOMBS_5: - case RG_BUY_BOMBS_525: - case RG_BUY_BOMBS_535: - return GI_BOMBS_5; - case RG_BOMBS_10: - case RG_BUY_BOMBS_10: - return GI_BOMBS_10; - case RG_BOMBS_20: - case RG_BUY_BOMBS_20: - return GI_BOMBS_20; - case RG_BUY_BOMBS_30: - return GI_BOMBS_30; - case RG_PROGRESSIVE_BOW: - switch (CUR_UPG_VALUE(UPG_QUIVER)) { - case 0: - return GI_BOW; - case 1: - return GI_QUIVER_40; - case 2: - return GI_QUIVER_50; - case 3: - case 4: - return infiniteUpgrades == RO_INF_UPGRADES_PROGRESSIVE ? (GetItemID)RG_QUIVER_INF : GI_QUIVER_50; - } - case RG_ARROWS_5: - case RG_BUY_ARROWS_10: - return GI_ARROWS_SMALL; - case RG_ARROWS_10: - case RG_BUY_ARROWS_30: - return GI_ARROWS_MEDIUM; - case RG_ARROWS_30: - case RG_BUY_ARROWS_50: - return GI_ARROWS_LARGE; - case RG_PROGRESSIVE_SLINGSHOT: - switch (CUR_UPG_VALUE(UPG_BULLET_BAG)) { - case 0: - return GI_SLINGSHOT; - case 1: - return GI_BULLET_BAG_40; - case 2: - return GI_BULLET_BAG_50; - case 3: - case 4: - return infiniteUpgrades == RO_INF_UPGRADES_PROGRESSIVE ? (GetItemID)RG_BULLET_BAG_INF : GI_BULLET_BAG_50; - } - case RG_DEKU_SEEDS_30: - case RG_BUY_DEKU_SEEDS_30: - return GI_SEEDS_30; - case RG_PROGRESSIVE_OCARINA: - switch (INV_CONTENT(ITEM_OCARINA_FAIRY)) { - case ITEM_NONE: - return GI_OCARINA_FAIRY; - case ITEM_OCARINA_FAIRY: - case ITEM_OCARINA_TIME: - return GI_OCARINA_OOT; - } - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BUY_BOMBCHUS_10: - return GI_BOMBCHUS_10; - case RG_BOMBCHU_20: - case RG_BUY_BOMBCHUS_20: - return GI_BOMBCHUS_20; - case RG_PROGRESSIVE_BOMBCHUS: - if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { - return (GetItemID)RG_PROGRESSIVE_BOMBCHUS; - } else if (infiniteUpgrades != RO_INF_UPGRADES_OFF) { - return (GetItemID)RG_BOMBCHU_INF; - } else if (AMMO(ITEM_BOMBCHU) < 5) { - return GI_BOMBCHUS_10; - } else { - return GI_BOMBCHUS_5; - } - case RG_PROGRESSIVE_HOOKSHOT: - switch (INV_CONTENT(ITEM_HOOKSHOT)) { - case ITEM_NONE: - return GI_HOOKSHOT; - case ITEM_HOOKSHOT: - case ITEM_LONGSHOT: - return GI_LONGSHOT; - } - case RG_BOOMERANG: - return GI_BOOMERANG; - case RG_LENS_OF_TRUTH: - return GI_LENS; - case RG_MAGIC_BEAN: - return GI_BEAN; - case RG_MEGATON_HAMMER: - return GI_HAMMER; - case RG_FIRE_ARROWS: - return GI_ARROW_FIRE; - case RG_ICE_ARROWS: - return GI_ARROW_ICE; - case RG_LIGHT_ARROWS: - return GI_ARROW_LIGHT; - case RG_DINS_FIRE: - return GI_DINS_FIRE; - case RG_FARORES_WIND: - return GI_FARORES_WIND; - case RG_NAYRUS_LOVE: - return GI_NAYRUS_LOVE; - - // Bottles - case RG_EMPTY_BOTTLE: - return GI_BOTTLE; - case RG_BOTTLE_WITH_MILK: - return GI_MILK_BOTTLE; - case RG_RUTOS_LETTER: - return GI_LETTER_RUTO; - - // Bottle Refills - case RG_MILK: - return GI_MILK; - case RG_RED_POTION_REFILL: - case RG_BUY_RED_POTION_30: - case RG_BUY_RED_POTION_40: - case RG_BUY_RED_POTION_50: - return GI_POTION_RED; - case RG_GREEN_POTION_REFILL: - case RG_BUY_GREEN_POTION: - return GI_POTION_GREEN; - case RG_BLUE_POTION_REFILL: - case RG_BUY_BLUE_POTION: - return GI_POTION_BLUE; - case RG_FISH: - case RG_BUY_FISH: - return GI_FISH; - case RG_BUY_BLUE_FIRE: - return GI_BLUE_FIRE; - case RG_BUY_BOTTLE_BUG: - return GI_BUGS; - case RG_BUY_POE: - return GI_POE; - case RG_BUY_FAIRYS_SPIRIT: - return GI_FAIRY; - - // Trade Items - case RG_WEIRD_EGG: - return GI_WEIRD_EGG; - case RG_ZELDAS_LETTER: - return GI_LETTER_ZELDA; - case RG_POCKET_EGG: - return GI_POCKET_EGG; - case RG_COJIRO: - return GI_COJIRO; - case RG_ODD_MUSHROOM: - return GI_ODD_MUSHROOM; - case RG_ODD_POTION: - return GI_ODD_POTION; - case RG_POACHERS_SAW: - return GI_SAW; - case RG_BROKEN_SWORD: - return GI_SWORD_BROKEN; - case RG_PRESCRIPTION: - return GI_PRESCRIPTION; - case RG_EYEBALL_FROG: - return GI_FROG; - case RG_EYEDROPS: - return GI_EYEDROPS; - case RG_CLAIM_CHECK: - return GI_CLAIM_CHECK; - - // Misc Items - case RG_STONE_OF_AGONY: - return GI_STONE_OF_AGONY; - case RG_GERUDO_MEMBERSHIP_CARD: - return GI_GERUDO_CARD; - case RG_GOLD_SKULLTULA_TOKEN: - return GI_SKULL_TOKEN; - case RG_PROGRESSIVE_STRENGTH: - switch (CUR_UPG_VALUE(UPG_STRENGTH)) { - case 0: - return GI_BRACELET; - case 1: - return GI_GAUNTLETS_SILVER; - case 2: - case 3: - return GI_GAUNTLETS_GOLD; - } - case RG_PROGRESSIVE_WALLET: - if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) { - return (GetItemID)RG_CHILD_WALLET; - } - switch (CUR_UPG_VALUE(UPG_WALLET)) { - case 0: - return GI_WALLET_ADULT; - case 1: - return GI_WALLET_GIANT; - case 2: - return tycoonWallet ? (GetItemID)RG_TYCOON_WALLET : infiniteUpgrades != RO_INF_UPGRADES_OFF ? (GetItemID)RG_WALLET_INF : GI_WALLET_GIANT; - case 3: - case 4: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? (GetItemID)RG_WALLET_INF : tycoonWallet ? (GetItemID)RG_TYCOON_WALLET : GI_WALLET_GIANT; - } - case RG_PROGRESSIVE_SCALE: - if (!Flags_GetRandomizerInf(RAND_INF_CAN_SWIM)) { - return (GetItemID)RG_BRONZE_SCALE; - } - switch (CUR_UPG_VALUE(UPG_SCALE)) { - case 0: - return GI_SCALE_SILVER; - case 1: - case 2: - return GI_SCALE_GOLD; - } - case RG_PROGRESSIVE_MAGIC_METER: - switch (gSaveContext.magicLevel) { - case 0: - return (GetItemID)RG_MAGIC_SINGLE; - case 1: - return (GetItemID)RG_MAGIC_DOUBLE; - case 2: - case 3: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? (GetItemID)RG_MAGIC_INF : (GetItemID)RG_MAGIC_DOUBLE; - } - - case RG_RECOVERY_HEART: - case RG_BUY_HEART: - return GI_HEART; - case RG_GREEN_RUPEE: - return GI_RUPEE_GREEN; - case RG_BLUE_RUPEE: - return GI_RUPEE_BLUE; - case RG_RED_RUPEE: - return GI_RUPEE_RED; - case RG_PURPLE_RUPEE: - return GI_RUPEE_PURPLE; - case RG_HUGE_RUPEE: - return GI_RUPEE_GOLD; - case RG_PIECE_OF_HEART: - return GI_HEART_PIECE; - case RG_HEART_CONTAINER: - return GI_HEART_CONTAINER; - - case RG_DEKU_NUTS_5: - case RG_BUY_DEKU_NUTS_5: - return GI_NUTS_5; - case RG_DEKU_NUTS_10: - case RG_BUY_DEKU_NUTS_10: - return GI_NUTS_10; - case RG_DEKU_STICK_1: - case RG_BUY_DEKU_STICK_1: - return GI_STICKS_1; - case RG_TREASURE_GAME_SMALL_KEY: - return GI_DOOR_KEY; - case RG_TREASURE_GAME_HEART: - return GI_HEART_PIECE_WIN; - case RG_TREASURE_GAME_GREEN_RUPEE: - return GI_RUPEE_GREEN_LOSE; - - //Ocarina Buttons - case RG_OCARINA_A_BUTTON: - return (GetItemID)RG_OCARINA_A_BUTTON; - case RG_OCARINA_C_LEFT_BUTTON: - return (GetItemID)RG_OCARINA_C_LEFT_BUTTON; - case RG_OCARINA_C_RIGHT_BUTTON: - return (GetItemID)RG_OCARINA_C_RIGHT_BUTTON; - case RG_OCARINA_C_UP_BUTTON: - return (GetItemID)RG_OCARINA_C_UP_BUTTON; - case RG_OCARINA_C_DOWN_BUTTON: - return (GetItemID)RG_OCARINA_C_DOWN_BUTTON; - - default: - if (!IsItemVanilla(randoGet)) { - return (GetItemID)randoGet; - } - return ogItemId; - } -} - -bool Randomizer::IsItemVanilla(RandomizerGet randoGet) { - switch (randoGet) { - case RG_NONE: - case RG_KOKIRI_SWORD: - case RG_GIANTS_KNIFE: - case RG_BIGGORON_SWORD: - case RG_DEKU_SHIELD: - case RG_HYLIAN_SHIELD: - case RG_MIRROR_SHIELD: - case RG_GORON_TUNIC: - case RG_ZORA_TUNIC: - case RG_IRON_BOOTS: - case RG_HOVER_BOOTS: - case RG_BOOMERANG: - case RG_LENS_OF_TRUTH: - case RG_MEGATON_HAMMER: - case RG_STONE_OF_AGONY: - case RG_DINS_FIRE: - case RG_FARORES_WIND: - case RG_NAYRUS_LOVE: - case RG_FIRE_ARROWS: - case RG_ICE_ARROWS: - case RG_LIGHT_ARROWS: - case RG_GERUDO_MEMBERSHIP_CARD: - case RG_MAGIC_BEAN: - case RG_WEIRD_EGG: - case RG_ZELDAS_LETTER: - case RG_RUTOS_LETTER: - case RG_POCKET_EGG: - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - case RG_GOLD_SKULLTULA_TOKEN: - case RG_PROGRESSIVE_HOOKSHOT: - case RG_PROGRESSIVE_STRENGTH: - return true; - case RG_PROGRESSIVE_BOMB_BAG: - if (CUR_UPG_VALUE(UPG_BOMB_BAG) < 3) { - return true; - } else { - return false; - } - case RG_PROGRESSIVE_BOW: - if (CUR_UPG_VALUE(UPG_QUIVER) < 3) { - return true; - } else { - return false; - } - case RG_PROGRESSIVE_SLINGSHOT: - if (CUR_UPG_VALUE(UPG_BULLET_BAG) < 3) { - return true; - } else { - return false; - } - case RG_PROGRESSIVE_NUT_UPGRADE: - if (CUR_UPG_VALUE(UPG_NUTS) < 3) { - return true; - } else { - return false; - } - case RG_PROGRESSIVE_STICK_UPGRADE: - if (CUR_UPG_VALUE(UPG_STICKS) < 3) { - return true; - } else { - return false; - } - case RG_PROGRESSIVE_OCARINA: - case RG_PROGRESSIVE_GORONSWORD: - case RG_EMPTY_BOTTLE: - case RG_BOTTLE_WITH_MILK: - case RG_RECOVERY_HEART: - case RG_GREEN_RUPEE: - case RG_BLUE_RUPEE: - case RG_RED_RUPEE: - case RG_PURPLE_RUPEE: - case RG_HUGE_RUPEE: - case RG_PIECE_OF_HEART: - case RG_HEART_CONTAINER: - case RG_MILK: - case RG_FISH: - case RG_BOMBS_5: - case RG_BOMBS_10: - case RG_BOMBS_20: - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - return true; - case RG_PROGRESSIVE_BOMBCHUS: - return INV_CONTENT(ITEM_BOMBCHU) != ITEM_NONE && !GetRandoSettingValue(RSK_INFINITE_UPGRADES); - case RG_ARROWS_5: - case RG_ARROWS_10: - case RG_ARROWS_30: - case RG_DEKU_NUTS_5: - case RG_DEKU_NUTS_10: - case RG_DEKU_SEEDS_30: - case RG_DEKU_STICK_1: - case RG_RED_POTION_REFILL: - case RG_GREEN_POTION_REFILL: - case RG_BLUE_POTION_REFILL: - case RG_TREASURE_GAME_HEART: - case RG_TREASURE_GAME_GREEN_RUPEE: - case RG_BUY_DEKU_NUTS_5: - case RG_BUY_ARROWS_30: - case RG_BUY_ARROWS_50: - case RG_BUY_BOMBS_525: - case RG_BUY_DEKU_NUTS_10: - case RG_BUY_DEKU_STICK_1: - case RG_BUY_BOMBS_10: - case RG_BUY_FISH: - case RG_BUY_RED_POTION_30: - case RG_BUY_GREEN_POTION: - case RG_BUY_BLUE_POTION: - case RG_BUY_HYLIAN_SHIELD: - case RG_BUY_DEKU_SHIELD: - case RG_BUY_GORON_TUNIC: - case RG_BUY_ZORA_TUNIC: - case RG_BUY_HEART: - case RG_BUY_BOMBCHUS_10: - case RG_BUY_BOMBCHUS_20: - case RG_BUY_DEKU_SEEDS_30: - case RG_SOLD_OUT: - case RG_BUY_BLUE_FIRE: - case RG_BUY_BOTTLE_BUG: - case RG_BUY_POE: - case RG_BUY_FAIRYS_SPIRIT: - case RG_BUY_ARROWS_10: - case RG_BUY_BOMBS_20: - case RG_BUY_BOMBS_30: - case RG_BUY_BOMBS_535: - case RG_BUY_RED_POTION_40: - case RG_BUY_RED_POTION_50: - return true; - case RG_PROGRESSIVE_SCALE: - if (!Flags_GetRandomizerInf(RAND_INF_CAN_SWIM)) { - return false; - } - return true; - case RG_PROGRESSIVE_WALLET: - if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) { - return false; - } - if (CUR_UPG_VALUE(UPG_WALLET) < 2) { - return true; - } else { - return false; - } - default: - return false; - } -} - -bool Randomizer::CheckContainsVanillaItem(RandomizerCheck randoCheck) { - RandomizerGet randoGet = Rando::Context::GetInstance()->GetItemLocation(randoCheck)->GetPlacedRandomizerGet(); - return IsItemVanilla(randoGet); -} - // There has been some talk about potentially just using the RC identifier to store flags rather than randomizer inf, so // for now we're not going to store randomzierInf in the randomizer check objects, we're just going to map them 1:1 here std::map rcToRandomizerInf = { @@ -1582,15 +1080,6 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, specialRc = RC_DODONGOS_CAVERN_GOSSIP_STONE; } break; - case SCENE_GROTTOS: - // Grotto fish are identified by respawn data - if (actorId == ACTOR_EN_FISH && actorParams == 1) { - int8_t data = gSaveContext.respawn[RESPAWN_MODE_RETURN].data; - if (Rando::StaticData::randomizerGrottoFishMap.contains(data)) { - specialRc = Rando::StaticData::randomizerGrottoFishMap[data]; - } - } - break; } if (specialRc != RC_UNKNOWN_CHECK) { @@ -1655,9 +1144,13 @@ ShopItemIdentity Randomizer::IdentifyShopItem(s32 sceneNum, u8 slotIndex) { shopItemIdentity.itemPrice = -1; shopItemIdentity.enGirlAShopItem = 0x32; + if (slotIndex == 0) { + return shopItemIdentity; + } + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_GIRLA, // Bazaar (SHOP1) scene is reused, so if entering from Kak use debug scene to identify - (sceneNum == SCENE_BAZAAR && gSaveContext.entranceIndex == ENTR_BAZAAR_0) ? SCENE_TEST01 : sceneNum, slotIndex); + (sceneNum == SCENE_BAZAAR && gSaveContext.entranceIndex == ENTR_BAZAAR_0) ? SCENE_TEST01 : sceneNum, slotIndex - 1); if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { shopItemIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; @@ -1789,8 +1282,7 @@ void GenerateRandomizerImgui(std::string seed = "") { RandoMain::GenerateRando(excludedLocations, enabledTricks, seed); CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 0); - CVarSave(); - CVarLoad(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); generated = 1; } @@ -1813,13 +1305,6 @@ void RandomizerSettingsWindow::DrawElement() { generated = 0; randoThread.join(); } - - ImGui::SetNextWindowSize(ImVec2(920, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Randomizer Editor", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - bool disableEditingRandoSettings = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); if (disableEditingRandoSettings) { UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); @@ -2440,7 +1925,6 @@ void RandomizerSettingsWindow::DrawElement() { if (disableEditingRandoSettings) { UIWidgets::ReEnableComponent(""); } - ImGui::End(); } void RandomizerSettingsWindow::UpdateElement() { @@ -2528,7 +2012,7 @@ CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 te RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf); RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet(); CustomMessage shopItemName; - if (mysterious|| CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { + if (mysterious || CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { if (randomizerInf >= RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 && randomizerInf <= RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8) { shopItemName = { "Mysterious Item", @@ -2835,86 +2319,251 @@ void CreateNaviRandoMessages() { } } -void CreateIceTrapRandoMessages() { - CustomMessage IceTrapMessages[NUM_ICE_TRAP_MESSAGES] = { - { "You are a %bFOOL%w!", "Du bist ein %bDUMMKOPF%w!", "%bPauvre fou%w..." }, - - { "You are a %bFOWL%w!", "Du bist eine %bFrostbeule%w!", "Tu es un %bglaçon%w, Harry!" }, - - { "%bFOOL%w!", "%bDUMMKOPF%w!", "%bSot%w que tu es." }, - - { "You just got %bPUNKED%w!", "Du wurdest %beiskalt%w erwischt!", "Ça me %bglace%w le sang!" }, - - { "Stay %bfrosty%w, @.", "Es läuft Dir %beiskalt%w den Rücken&hinunter, @.", "%bReste au frais%w, @." }, - - { "Take a %bchill pill%w, @.", "Bleib %bcool%w, @.", "Et c'est la douche %bfroide%w!" }, - - { "%bWinter%w is coming.", "Der %bWinter%w naht.", "L'%bhiver%w vient." }, - - { "%bICE%w to see you, @.", "Alles %bcool%w im Pool?", "%bGlacier%w!" }, - - { "Feeling a little %rhot%w under the collar?&%bLet's fix that%w.", "%bAbkühlung gefällig%w?", - "%Ça en jette un %bfroid%w." }, - - { "It's a %bcold day%w in the Evil Realm.", "Es ist ein %kalter%w Tag im Herzen&von Hyrule.", - "Est-ce que tu as déjà eu des sueurs&%bfroides%w?" }, - - { "Getting %bcold feet%w?", "Bekommst Du etwa %bkalte%w Füße?", - "La vengeance est un plat qui se mange&%bfroid%w!" }, - - { "Say hello to the %bZoras%w for me!", "Sag den %bZoras%w viele Grüße von mir!", - "Dit bonjour aux %bZoras%w pour moi!" }, - - { "Can you keep a %bcool head%w?", "Bewahre einen %bkühlen%w! Kopf.", - "Il faut parfois savoir garder la tête&%bfroide%w!" }, - - { "Ganondorf used %bIce Trap%w!&It's super effective!", - "Ganondorf setzt %bEisstrahl%w ein.&Das ist sehr effektiv!", - "Ganondorf utilise %bPiège de Glace%w!&C'est super efficace!" }, - - { "Allow me to break the %bice%w!", "Ein Lächeln ist der beste Weg,&um das %bEis%w zu brechen!", - "Laisse moi briser la %bglace%w!" }, - - { "%bCold pun%w.", "%bEiskalt%w lässt du meine Seele&erfrier'n.", - "Balance man...,&Cadence man...,&Trace la %bglace%w...,&c'est le Cooooolllll Rasta!" }, - - { "The %bTitanic%w would be scared of you,&@.", "Die %bTitanic%w hätte Angst vor Dir,&@.", - "Le %bTitanic%w aurait peur de toi,&@." }, - - { "Oh no!", "Oh nein!", "Oh non!" }, - - { "What killed the dinosaurs?&The %bICE%w age!", "Was die Dinosaurier getötet hat?&Die %bEiszeit%w!", - "Qu'est-ce qui a tué les dinosaures?&L'ère %bglacière%w!" }, - - { "Knock knock. Who's there? Ice. Ice&who? Ice see that you're a %bFOOL%w.", - "Nachts ist es %bkälter%w als draußen.", - "L'imbécile réfléchit uniquement quand il&s'observe dans la %bglace%w." }, +CustomMessage Randomizer::GetIceTrapMessage() { + static const char* const englishIceTrapMessages[169] = { + "You are a #FOOL#!", + "You are a #FOWL#!", + "#FOOL#!", + "You just got #PUNKED#!", + "Stay #frosty#, @.", + "Take a #chill pill#, @.", + "#Winter# is coming.", + "#ICE# to see you, @.", + "Feeling a little %rhot%w under the collar? #Let's fix that#.", + "It's a #cold day# in the Evil Realm.", + "Getting #cold feet#?", + "Say hello to the #Zoras# for me!", + "Can you keep a #cool head#?", + "Ganondorf used #Ice Trap#!&It's super effective!", + "Allow me to break the #ice#!", + "#Cold pun#.", + "The #Titanic# would be scared of you, @.", + "Oh no!", + "Uh oh!", + "What killed the dinosaurs?&The #ICE# age!", + "Knock knock. Who's there? Ice. Ice who? Ice see that you're a #FOOL#.", + "Never gonna #give you up#. Never gonna #let you down#. Never gonna run around and #desert you#.", + "Thank you #@#! But your item is in another castle!", + "#FREEZE#! Don't move!", + "Wouldn't it be #ice# if we were colder?", + "Greetings from #Snowhead#! Wish you were here", + "Too #cool# for you?", + "#Ice#, #ice#, baby...", + "Time to break the #ice#.", + "We wish that you would read this... We wish that you would read this... But we set our bar low.", + "#Freeze# and put your hands in the air!", + "#Ice# to meet you!", + "Do you want to #freeze# a snowman?", + "Isn't there a #mansion# around here?", + "Now you know how #King Zora# feels", + "May the #Frost# be with you.", + "Carpe diem. #Freeze# the day.", + "There #snow# place like home.", + "That'll do, #ice#. That'll do.", + "All that is #cold# does not glitter, Not all those who wander are #frost#.", + "I Used To Be An Adventurer Like You. Then I Took An #Icetrap# To The Knee.", + "Would you like #ice# with that?", + "You have obtained the #Ice# Medallion!", + "Quick, do a #Zora# impression!", + "One item #on the rocks#!",//would be better if it could display the name of the item + "How much does a polar bear weigh?&Enough to break the #ice#.", + "You got Din's #Ice#!", + "You got Nayru's #Cold#!", + "You got Farore's #Freeze#!", + "KEKW", + "You just got #ICE TRAPPED#! Tag your friends to totally #ICE TRAP# them!", + "Are you okay, @? You're being #cold# today.", + "In a moment, your game might experience some #freezing#.", + "Breeze? Trees? Squeeze? No, it's a #freeze#!", + "After collecting this item, @ was assaulted in #cold# blood.", + "Only #chill# vibes around here!", + "Here's a #cool# gift for you!", + "Aha! You THOUGHT.", + "Stay hydrated and brush your teeth!", + "Isn't it too hot here? Let's turn the #AC# on.", + "One serving of #cold# @, coming right up!", + "Is it #cold# in here is that just me?", + "Yahaha! You found me!", + "You'd made a great #ice#-tronaut!", + "That's just the tip of the #iceberg#!", + "It's the triforce!&No, just kidding, it's an #ice trap#.", + "WINNER!", + "LOSER!", + "Greetings from #Cold Miser#!", + "Pardon me while I turn up the #AC#.", + "If you can't stand the #cold#, get out of the #freezer#.", + "Oh, goodie! #Frozen @# for the main course!", + "You have #freeze# power!", + "You obtained the #Ice Beam#! No wait, wrong game.", + "Here's to another lousy millenium!", + "You've activated my #trap card#!", + "I love #refrigerators#!", + "You expected an item,&BUT IT WAS I, AN #ICE TRAP#!", + "It's dangerous to go alone! Take #this#!", + "soh.exe has #stopped responding#.", + "Enough! My #Ice Trap# thaws in the morning!", + "Nobody expects the span-#ice# inquisition!", + "This is one #cool# item!", + "Say hello to my #little friend#!", + "We made you an offer you #can't refuse#.", + "Hyrule? More like #Hycool#!", + "Ice puns are #snow# problem!", + "This #ice# is #snow# joke!", + "There's no business like #snow# business!", + "no, dude", + "N#ice# trap ya got here!", + "Quick do your best impression of #Zoras Domain#!", + "Ganon used #ice beam#, it's super effective!", + "I was #frozen# today.", + "You're not in a #hurry#, right?", + "It's a #trap#!", + "At least it's not a VC crash and only Link is #frozen#!", + "Oh no! #BRAIN FREEZE#!", + "Looks like your game #froze#! Nope just you!", + "PK #FREEZE#!", + "May I interest you in some #iced# Tea?", + "Time for some Netflix and #chill#.", + "I know, I know... #FREEZE#!", + "#Ice# of you to drop by!", + "STOP!&You violated the #Thaw#!", + "I wanted to give you a treasure, but it looks like you got #cold feet#", + "You told me you wanted to deliver #just ice# to Ganondorf!", + "You got the triforce!&This ancient artifact of divine power can grant any- wait, no, sorry, it's just an ice trap. My bad", + "Time to #cool off#!", + "The #Ice Cavern# sends its regards.", + "Loading item, please #wait#...", + "Mash A+B to not #die#.", + "Sorry, your item is in another location.", //would be better if it could have the name of the item + "You only wish this was %gGreg%w.", + "Do you want to drink a hot chocolate?", + "The #cold# never bothered me anyway", + "Hope you're too school for #cool#!", + "Be thankful this isn't #absolute zero#.", + "Did you know the F in ZFG stands for #Freeze#?", + "You got #Ice Age (2002)#!", + "Now you can cast a #spell# you don't know", + "How's about a hero #on the rocks#?", + "Ain't no tunic for #this#!", + "I knew you were #part metroid#!", + "That's just the #icing on the cake#!", + "You're so #cool#, @!", + "You found #disappointment#!", + "You got #FOOLED#!", + "Start Mashing.", + "This item will #self-destruct# in 5 seconds...", + "Remember, there may be some momentary #discomfort#.", + "In a perfect world #ice traps# like me would not exist, but this is not a perfect world.", + "Gee, it sure is #cold# around here.", + "You tested the item with your #ice detector#, it beeped.", //would be better if it could have the name of the item + "You have found the way of the zero. The #sub-zero#.", + "Mweep... mweep... mweep...", + "Scum, #freezebag#! I mean #freeze#, scumbag!", + "Is it #chilly# in here or is it just #you#?", + "#Proceed#", + "WHAT'S SHE GONNA DO, MAKE ME AN #[Ice Cream]#!?", + "You've met with a #terrible fate#, haven't you?", + "So I heard you like the Shining, here's how it #ends#.", + "Minor routing mistake. #I win#.", + "Hold this #L#, @.", + "#SKILL ISSUE#", + "All you heat are belong to us", + "Wait a second, don't you already have #this item#?", + "#Freeze#! We have you surrounded!", + "Error 404 - Item not #found#.", + "Hydration break! Hey, who #froze# my water?", + "Oops, wrong #item model#.", + "Whoops! You have to put the item #in your inventory#.", + "You dropped the item, shattering it into #shards of ice#!", //would be better if it could have the name of the item + "Is this... golden age Simpsons?&BECAUSE I'M ABOUT TO #CHOKE A CHILD#.", + "You are the weakest @, #goodbye#!", + "Ugh... Why did we even randomize #this item#?", + "The #Frost Moon# is rising...", + "According to all known laws of physics and biology, there is no way that @ should be able to survive #getting fully encased in ice#. The cells in @'s body would all die by the time they #unthaw#. Of course, this is a video game, so @ survives anyway... #Probably#.", + "Okay, so stop me if you've heard this one - a gamer and a bottle of #liquid nitrogen# walk into a milk bar...", + "Lástima, es una #trampa de hielo#...&&Nobody expects the Spanish #ice trap#!", + "Gee, it sure is #BURR#ing around here.", + "Navi? Oh! I thought she was called #Névé#!", + "It's fine, @ knew this was a #trap#, they're just using it to take damage intentionally to manipulate RNG.", + "Unfortunately, the item has #stopped#.", //would be better if it could have the name of the item + "This item is #not available# in your country.", //would be better if it could have the name of the item + "#Ice# try. #;)#", + "D'oh, I #missed#!", + "Where is my #super suit#?", + "#Titanic's revenge#.", + }; - { "Never gonna %bgive you up%w. Never&gonna %blet you down%w. Never gonna&run around and %bdesert you%w.", - "Never gonna %bgive you up%w. Never&gonna %blet you down%w. Never gonna&run around and %bdesert you%w.", - "Never gonna %bgive you up%w. Never&gonna %blet you down%w. Never gonna&run around and %bdesert you%w." }, + static const char* const germanIceTrapMessages[23] = { + "Du bist ein #DUMMKOPF#!", + "Du bist eine #Frostbeule#!", + "#DUMMKOPF#!", + "Du wurdest #eiskalt# erwischt!", + "Es läuft Dir #eiskalt# den Rücken hinunter, @.", + "Bleib #cool#, @.", + "Der #Winter# naht.", + "Alles #cool# im Pool?", + "#Abkühlung gefällig#?", + "Es ist ein %kalter%w Tag im Herzen von Hyrule.", + "Bekommst Du etwa #kalte# Füße?", + "Sag den #Zoras# viele Grüße von mir!", + "Bewahre einen #kühlen#! Kopf.", + "Ganondorf setzt #Eisstrahl# ein. Das ist sehr effektiv!", + "Ein Lächeln ist der beste Weg, um das #Eis# zu brechen!", + "#Eiskalt# lässt du meine Seele erfrier'n.", + "Die #Titanic# hätte Angst vor Dir, @.", + "Oh nein!", + "Was die Dinosaurier getötet hat?&Die #Eiszeit#!", + "Nachts ist es #kälter# als draußen.", + "Never gonna #give you up#. Never gonna #let you down#. Never gonna run around and #desert you#.", + "Danke #@#! Aber der Gegenstand ist in einem anderem Schloß!", + "Kalt. Kalt. Kälter. #EISKALT#!", + }; - { "Thank you %b@%w!&But your item is in another castle!", - "Danke %b@%w!&Aber der Gegenstand ist in&einem anderem Schloß!", - "Merci %b@%w!&Mais ton objet est dans un autre&château!" }, + static const char* const frenchIceTrapMessages[23] = { + "#Pauvre fou#...", + "Tu es un #glaçon#, Harry!", + "#Sot# que tu es.", + "Ça me #glace# le sang!", + "#Reste au frais#, @.", + "Et c'est la douche #froide#!", + "L'#hiver# vient.", + "#Glacier#!", + "Ça en jette un #froid#.", + "Est-ce que tu as déjà eu des sueurs #froides#?", + "La vengeance est un plat qui se mange #froid#!", + "Dit bonjour aux #Zoras# pour moi!", + "Il faut parfois savoir garder la tête #froide#!", + "Ganondorf utilise #Piège de Glace#! C'est super efficace!", + "Laisse moi briser la #glace#!", + "Balance man..., Cadence man..., Trace la #glace#..., c'est le Cooooolllll Rasta!", + "Le #Titanic# aurait peur de toi, @.", + "Oh non!", + "Qu'est-ce qui a tué les dinosaures?&L'ère #glacière#!", + "L'imbécile réfléchit uniquement quand il s'observe dans la #glace#.", + "Never gonna #give you up#. Never gonna #let you down#. Never gonna run around and #desert you#.", + "Merci #@#! Mais ton objet est dans un autre château!", + "J'espère que ça ne te fait ni chaud, ni #froid#.", + }; - { "%bFREEZE%w! Don't move!", " Kalt. Kalt. Kälter. %bEISKALT%w!", - "J'espère que ça ne te fait ni chaud, ni&%bfroid%w." }, + CustomMessage msg; - }; - CustomMessageManager* customMessageManager = CustomMessageManager::Instance; - customMessageManager->AddCustomMessageTable(Randomizer::IceTrapRandoMessageTableID); - for (u8 i = 0; i <= (NUM_ICE_TRAP_MESSAGES - 1); i++) { - customMessageManager->CreateMessage(Randomizer::IceTrapRandoMessageTableID, i, - IceTrapMessages[i]); + if (CVarGetInteger(CVAR_GENERAL("LetItSnow"), 0)) { + msg = CustomMessage( + /*english*/ "This year for Christmas, all you get is #COAL#!", + /*german*/ "This year for Christmas, all you get is #COAL#!", + /*french*/ "Pour Noël, cette année, tu n'auras que du #CHARBON#! %rJoyeux Noël%w!", + { QM_BLUE } + ); + } else { + msg = CustomMessage( + RandomElement(englishIceTrapMessages), + RandomElement(germanIceTrapMessages), + RandomElement(frenchIceTrapMessages), + { QM_BLUE, QM_BLUE, QM_BLUE } + ); } - // We only use this ice trap message for christmas, so we don't want it in the normal ice trap messages rotation - customMessageManager->CreateMessage( - Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1, - CustomMessage("This year for Christmas, all&you get is %BCOAL%w!", - "This year for Christmas, all&you get is %BCOAL%w!", - "Pour Noël, cette année, tu&n'auras que du %BCHARBON!&%rJoyeux Noël%w!")); + msg.AutoFormat(); + return msg; } static int goronIDs[9] = { 0x3052, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070 }; @@ -3299,7 +2948,6 @@ void Randomizer::CreateCustomMessages() { CreateRupeeMessages(); CreateTriforcePieceMessages(); CreateNaviRandoMessages(); - CreateIceTrapRandoMessages(); CreateFireTempleGoronMessages(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 3e6df621335..14f28311cd3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -20,13 +20,11 @@ #define MAX_SEED_STRING_SIZE 1024 #define NUM_TRIFORCE_PIECE_MESSAGES 6 #define NUM_NAVI_MESSAGES 19 -#define NUM_ICE_TRAP_MESSAGES 23 #define NUM_GORON_MESSAGES 9 class Randomizer { private: std::unordered_map randoSettings; - bool IsItemVanilla(RandomizerGet randoGet); public: Randomizer(); @@ -57,7 +55,6 @@ class Randomizer { FishIdentity IdentifyFish(s32 sceneNum, s32 actorParams); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, bool checkObtainability = true); - GetItemID GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItemID ogItemId); ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck); CustomMessage GetSheikMessage(s16 scene, u16 originalTextId); @@ -68,8 +65,8 @@ class Randomizer { CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry); static void CreateCustomMessages(); static CustomMessage GetRupeeMessage(u16 rupeeTextId); + static CustomMessage GetIceTrapMessage(); static CustomMessage GetTriforcePieceMessage(); - bool CheckContainsVanillaItem(RandomizerCheck randoCheck); }; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 01cddabbc86..3476d4fa7eb 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -27,16 +27,6 @@ typedef struct { uint8_t id; } Sprite; -// Check tracker check visibility categories -typedef enum { - RCSHOW_UNCHECKED, - RCSHOW_SEEN, - RCSHOW_IDENTIFIED, - RCSHOW_SCUMMED, - RCSHOW_COLLECTED, - RCSHOW_SAVED, -} RandomizerCheckStatus; - typedef enum { HINT_TYPE_HINT_KEY, HINT_TYPE_AREA, @@ -257,23 +247,25 @@ typedef enum { RCTYPE_COW, // Cows RCTYPE_ADULT_TRADE, // Adult trade quest checks RCTYPE_FROG_SONG, // Frog song purple rupee checks - RCTYPE_MAP_COMPASS, // Maps/Compasses + RCTYPE_MAP, // Maps + RCTYPE_COMPASS, // Compasses RCTYPE_SMALL_KEY, // Small Keys RCTYPE_GF_KEY, // Gerudo Fortress Keys RCTYPE_BOSS_KEY, // Boss Keys RCTYPE_GANON_BOSS_KEY, // Ganon's boss key - RCTYPE_SHOP, // shops - RCTYPE_SCRUB, // scrubs - RCTYPE_MERCHANT, // merchants + RCTYPE_SHOP, // Shops + RCTYPE_SCRUB, // Scrubs + RCTYPE_MERCHANT, // Merchants RCTYPE_CHEST_GAME, // RANDOTODO replace this once we implement it, just using it to exclude for now RCTYPE_LINKS_POCKET, // RANDOTODO this feels hacky, replace with better starting items RCTYPE_GOSSIP_STONE, // RANDOTODO make these into event access + RCTYPE_STATIC_HINT, // RANDOTODO make these into event access RCTYPE_SONG_LOCATION, // Song locations RCTYPE_BOSS_HEART_OR_OTHER_REWARD, // Boss heart container or lesser dungeon rewards (lens, ice arrow) RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives - RCTYPE_FISH, + RCTYPE_FISH, // Fishes } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -315,6 +307,16 @@ typedef enum { RCAREA_INVALID } RandomizerCheckArea; +// Check tracker check visibility categories +typedef enum { + RCSHOW_UNCHECKED, + RCSHOW_SEEN, + RCSHOW_IDENTIFIED, + RCSHOW_SCUMMED, + RCSHOW_COLLECTED, + RCSHOW_SAVED, +} RandomizerCheckStatus; + typedef enum { RR_NONE, RR_ROOT, @@ -537,17 +539,25 @@ typedef enum { RR_DODONGOS_CAVERN_MQ_BEGINNING, RR_DODONGOS_CAVERN_MQ_LOBBY, - RR_DODONGOS_CAVERN_MQ_ELEVATOR, - RR_DODONGOS_CAVERN_MQ_ABOVE_STAIRCASE, + RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, + RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, + RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, + RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, + RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, + RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, + RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM, - RR_DODONGOS_CAVERN_MQ_BEFORE_UPPER_LIZALFOS, + RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, + RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, RR_DODONGOS_CAVERN_MQ_POES_ROOM, - RR_DODONGOS_CAVERN_MQ_MOUTH, - RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, + RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, + RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, + RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, + RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, @@ -2176,6 +2186,7 @@ typedef enum { RG_DISTANT_SCARECROW, RG_STICKS, RG_NUTS, + RG_EPONA, RG_MAX } RandomizerGet; @@ -3658,17 +3669,21 @@ typedef enum { RSG_LOGIC, RSG_EXCLUDES_KOKIRI_FOREST, RSG_EXCLUDES_LOST_WOODS, + RSG_EXCLUDES_SACRED_FOREST_MEADOW, RSG_EXCLUDES_DEKU_TREE, RSG_EXCLUDES_FOREST_TEMPLE, RSG_EXCLUDES_KAKARIKO_VILLAGE, + RSG_EXCLUDES_GRAVEYARD, RSG_EXCLUDES_BOTTOM_OF_THE_WELL, RSG_EXCLUDES_SHADOW_TEMPLE, - RSG_EXCLUDES_DEATH_MOUNTAIN, + RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL, + RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER, RSG_EXCLUDES_GORON_CITY, RSG_EXCLUDES_DODONGOS_CAVERN, RSG_EXCLUDES_FIRE_TEMPLE, RSG_EXCLUDES_ZORAS_RIVER, RSG_EXCLUDES_ZORAS_DOMAIN, + RSG_EXCLUDES_ZORAS_FOUNTAIN, RSG_EXCLUDES_JABU_JABU, RSG_EXCLUDES_ICE_CAVERN, RSG_EXCLUDES_HYRULE_FIELD, @@ -3676,9 +3691,13 @@ typedef enum { RSG_EXCLUDES_LAKE_HYLIA, RSG_EXCLUDES_WATER_TEMPLE, RSG_EXCLUDES_GERUDO_VALLEY, + RSG_EXCLUDES_GERUDO_FORTRESS, + RSG_EXCLUDES_HAUNTED_WASTELAND, + RSG_EXCLUDES_DESERT_COLOSSUS, RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS, RSG_EXCLUDES_SPIRIT_TEMPLE, RSG_EXCLUDES_HYRULE_CASTLE, + RSG_EXCLUDES_MARKET, RSG_EXCLUDES_GANONS_CASTLE, RSG_EXCLUDES, RSG_TRICKS, @@ -3763,6 +3782,7 @@ typedef enum { RSK_SHUFFLE_SONGS, RSK_SHUFFLE_TOKENS, RSK_SHOPSANITY, + RSK_SHOPSANITY_COUNT, RSK_SHOPSANITY_PRICES, RSK_SHOPSANITY_PRICES_AFFORDABLE, RSK_SHUFFLE_SCRUBS, @@ -3893,13 +3913,6 @@ typedef enum { RSK_MAX } RandomizerSettingKey; -typedef struct { - RandomizerCheckStatus status; - uint16_t skipped; - int16_t price; - uint16_t hintItem; -} RandomizerCheckTrackerData; - //Generic Settings (any binary option can use this) // off/on typedef enum { @@ -3979,17 +3992,26 @@ typedef enum { RO_BRIDGE_WILDCARD_REWARD, } RandoOptionBridgeRewards; -//Shopsanity settings (off, 0-4 items, random) +//Shopsanity settings (off, specific count, random) typedef enum { RO_SHOPSANITY_OFF, - RO_SHOPSANITY_ZERO_ITEMS, - RO_SHOPSANITY_ONE_ITEM, - RO_SHOPSANITY_TWO_ITEMS, - RO_SHOPSANITY_THREE_ITEMS, - RO_SHOPSANITY_FOUR_ITEMS, + RO_SHOPSANITY_SPECIFIC_COUNT, RO_SHOPSANITY_RANDOM, } RandoOptionShopsanity; +//Shopsanity count settings (0-7 items) +typedef enum { + RO_SHOPSANITY_COUNT_ZERO_ITEMS, + RO_SHOPSANITY_COUNT_ONE_ITEM, + RO_SHOPSANITY_COUNT_TWO_ITEMS, + RO_SHOPSANITY_COUNT_THREE_ITEMS, + RO_SHOPSANITY_COUNT_FOUR_ITEMS, + RO_SHOPSANITY_COUNT_FIVE_ITEMS, + RO_SHOPSANITY_COUNT_SIX_ITEMS, + RO_SHOPSANITY_COUNT_SEVEN_ITEMS, + RO_SHOPSANITY_COUNT_EIGHT_ITEMS, +} RandoOptionShopsanityCount; + //Shopsanity price ranges typedef enum { RO_SHOPSANITY_PRICE_BALANCED, //Balanced random from 0-300 @@ -4338,4 +4360,22 @@ typedef enum { TH_MESSAGE_SURPLUS, } TriforceHuntMessages; +typedef enum { + RE_GOLD_SKULLTULA, + RE_BIG_SKULLTULA, + RE_DODONGO, + RE_LIZALFOS, + RE_GOHMA_LARVA, + RE_KEESE, + RE_FIRE_KEESE, + RE_MAD_SCRUB, +} RandomizerEnemy; +typedef enum { + ED_CLOSE, + ED_HAMMER_JUMPSLASH, + ED_MASTER_SWORD_JUMPSLASH, + ED_RANG_OR_HOOKSHOT, + ED_LONGSHOT, + ED_FAR, +} EnemyDistance; diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 3b5eed450f7..45bb928acbd 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -119,8 +119,16 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_SET_NUMBER || CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) < 12) // at least one vanilla dungeon ) && - (location.GetRCType() != RCTYPE_SHOP || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF) > RO_SHOPSANITY_ZERO_ITEMS) && + ( + location.GetRCType() != RCTYPE_SHOP || + !( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) + ) + ) + ) && (location.GetRCType() != RCTYPE_SCRUB || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_OFF) != RO_SCRUBS_OFF || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || @@ -143,8 +151,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { (location.GetRCType() != RCTYPE_OCARINA || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_NO)) && // ocarina locations (location.GetRandomizerCheck() != RC_HC_ZELDAS_LETTER) && // don't show until we support shuffling letter - (location.GetRCType() != - RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?) + (location.GetRCType() != RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?) + (location.GetRCType() != RCTYPE_STATIC_HINT) && // don't show static hints (location.GetRCType() != RCTYPE_LINKS_POCKET) && // links pocket can be set to nothing if needed (location.GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them @@ -169,7 +177,7 @@ 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_MAP_COMPASS || + ((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && (location.GetRCType() != RCTYPE_SMALL_KEY || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 29b99106b93..469a16f762f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -36,21 +36,6 @@ extern std::vector equipmentItems; using json = nlohmann::json; -void to_json(json& j, const RandomizerCheckTrackerData& rctd) { - j = json { - { "status", rctd.status == RCSHOW_COLLECTED ? RCSHOW_SAVED : rctd.status }, - { "skipped", rctd.skipped }, - { "price", rctd.price }, - { "hintItem", rctd.hintItem }}; - } - -void from_json(const json& j, RandomizerCheckTrackerData& rctd) { - j.at("status").get_to(rctd.status); - j.at("skipped").get_to(rctd.skipped); - j.at("hintItem").get_to(rctd.hintItem); - j.at("price").get_to(rctd.price); -} - namespace CheckTracker { // settings @@ -149,13 +134,12 @@ OSContPad* trackerButtonsPressed; std::unordered_map checkNameOverrides; bool ShouldShowCheck(RandomizerCheck rc); -bool ShouldHideArea(RandomizerCheckArea rcArea); +bool UpdateFilters(); void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0); bool CompareChecks(RandomizerCheck, RandomizerCheck); bool CheckByArea(RandomizerCheckArea); void DrawLocation(RandomizerCheck); void EndFloatWindows(); -bool HasItemBeenCollected(RandomizerCheck); void LoadSettings(); void RainbowTick(); void UpdateAreas(RandomizerCheckArea area); @@ -219,39 +203,35 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; - -void DefaultCheckData(RandomizerCheck rc) { - gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED; - gSaveContext.checkTrackerData[rc].skipped = 0; - gSaveContext.checkTrackerData[rc].hintItem = RC_UNKNOWN_CHECK; -} +std::array filterAreasHidden = { 0 }; +std::array filterChecksHidden = { 0 }; void SongFromImpa() { if (IS_RANDO) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA) == RO_GENERIC_ON && IS_RANDO) { - if (gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status != RCSHOW_SAVED) { - gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status = RCSHOW_SAVED; - } + //if (gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status != RCSHOW_SAVED) { + // gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status = RCSHOW_SAVED; + //} } } } void GiftFromSages() { if (!IS_RANDO) { - DefaultCheckData(RC_GIFT_FROM_SAGES); + //DefaultCheckData(RC_GIFT_FROM_SAGES); } } std::vector checks; // Function for adding Link's Pocket check void LinksPocket() { - if (IS_RANDO) { + /*if (IS_RANDO) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING || OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DUNGEON_REWARDS) == RO_DUNGEON_REWARDS_END_OF_DUNGEON) { DefaultCheckData(RC_LINKS_POCKET); gSaveContext.checkTrackerData[RC_LINKS_POCKET].status = RCSHOW_SAVED; } - } + }*/ } void TrySetAreas() { @@ -280,37 +260,38 @@ uint16_t GetTotalChecksGotten() { return totalChecksGotten; } -void RecalculateAreaTotals() { - for (auto [rcArea, checks] : checksByArea) { - if (rcArea == RCAREA_INVALID) { - return; +void RecalculateAreaTotals(RandomizerCheckArea rcArea) { + areaChecksGotten[rcArea] = 0; + areaCheckTotals[rcArea] = 0; + for (auto rc : checksByArea.at(rcArea)) { + if (!IsVisibleInCheckTracker(rc)) { + continue; } - areaChecksGotten[rcArea] = 0; - areaCheckTotals[rcArea] = 0; - for (auto rc : checks) { - if (!IsVisibleInCheckTracker(rc)) { - continue; - } - areaCheckTotals[rcArea]++; - if (gSaveContext.checkTrackerData[rc].skipped || gSaveContext.checkTrackerData[rc].status == RCSHOW_COLLECTED - || gSaveContext.checkTrackerData[rc].status == RCSHOW_SAVED) { - areaChecksGotten[rcArea]++; - } + areaCheckTotals[rcArea]++; + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped() || OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->HasObtained()) { + areaChecksGotten[rcArea]++; } } + CalculateTotals(); +} - totalChecks = 0; - totalChecksGotten = 0; +void RecalculateAllAreaTotals() { + for (auto& [rcArea, checks] : checksByArea) { + if (rcArea == RCAREA_INVALID) { + return; + } + RecalculateAreaTotals(rcArea); + } } void SetCheckCollected(RandomizerCheck rc) { - gSaveContext.checkTrackerData[rc].status = RCSHOW_COLLECTED; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetCheckStatus(RCSHOW_COLLECTED); Rando::Location* loc = Rando::StaticData::GetLocation(rc); if (IsVisibleInCheckTracker(rc)) { - if (!gSaveContext.checkTrackerData[rc].skipped) { + if (!OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped()) { areaChecksGotten[loc->GetArea()]++; } else { - gSaveContext.checkTrackerData[rc].skipped = false; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); } } SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); @@ -427,6 +408,8 @@ void ClearAreaChecksAndTotals() { areaChecksGotten[rcArea] = 0; areaCheckTotals[rcArea] = 0; } + totalChecks = 0; + totalChecksGotten = 0; } void SetShopSeen(uint32_t sceneNum, bool prices) { @@ -439,8 +422,8 @@ void SetShopSeen(uint32_t sceneNum, bool prices) { } bool statusChanged = false; for (int i = start; i < start + 8; i++) { - if (gSaveContext.checkTrackerData[i].status == RCSHOW_UNCHECKED) { - gSaveContext.checkTrackerData[i].status = RCSHOW_SEEN; + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetCheckStatus() == RCSHOW_UNCHECKED) { + OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetCheckStatus(RCSHOW_SEEN); statusChanged = true; } } @@ -449,73 +432,23 @@ void SetShopSeen(uint32_t sceneNum, bool prices) { } } -bool HasItemBeenCollected(RandomizerCheck rc) { - if (gPlayState == nullptr) { - return false; - } - Rando::Location* x = Rando::StaticData::GetLocation(rc); - Rando::SpoilerCollectionCheck check = x->GetCollectionCheck(); - auto flag = check.flag; - auto scene = check.scene; - auto type = check.type; - - switch (type) { - case SpoilerCollectionCheckType::SPOILER_CHK_ALWAYS_COLLECTED: - return true; - case SpoilerCollectionCheckType::SPOILER_CHK_CHEST: - return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.chest & (1 << flag)) || - gSaveContext.sceneFlags[scene].chest & (1 << flag); - case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE: - return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.collect & (1 << flag)) || - gSaveContext.sceneFlags[scene].collect & (1 << flag); - case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM: - case SpoilerCollectionCheckType::SPOILER_CHK_FISH: - case SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF: - case SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD: - return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)); - case SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF: - return gSaveContext.eventChkInf[flag / 16] & (0x01 << flag % 16); - case SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA: - return GET_GS_FLAGS(scene) & flag; - case SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE: - return gSaveContext.infTable[scene] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); - case SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF: - return gSaveContext.itemGetInf[flag / 16] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); - case SpoilerCollectionCheckType::SPOILER_CHK_NONE: - return false; - case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER: - // Gravedigger has a fix in place that means one of two save locations. Check both. - return (gSaveContext.itemGetInf[1] & 0x1000) || // vanilla flag - ((IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("GravediggingTourFix"), 0)) && - gSaveContext.sceneFlags[scene].collect & (1 << flag) || (gPlayState->actorCtx.flags.collect & (1 << flag))); // rando/fix flag - default: - return false; - } - return false; -} - void CheckTrackerLoadGame(int32_t fileNum) { LoadSettings(); TrySetAreas(); for (auto& entry : Rando::StaticData::GetLocationTable()) { RandomizerCheck rc = entry.GetRandomizerCheck(); - RandomizerCheckTrackerData rcTrackerData = gSaveContext.checkTrackerData[rc]; if (rc == RC_UNKNOWN_CHECK || rc == RC_MAX || rc == RC_LINKS_POCKET || !Rando::StaticData::GetLocation(rc) != RC_UNKNOWN_CHECK) { continue; } - Rando::Location* entry2; - if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) { - entry2 = Rando::StaticData::GetLocation(rc); - } else { - entry2 = Rando::StaticData::GetLocation(rc); - } + Rando::Location* entry2 = Rando::StaticData::GetLocation(rc); + Rando::ItemLocation* loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck()); if (IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) { areaCheckTotals[entry2->GetArea()]++; - if (rcTrackerData.status == RCSHOW_SAVED || rcTrackerData.skipped) { + if (loc->GetCheckStatus() == RCSHOW_SAVED || loc->GetIsSkipped()) { areaChecksGotten[entry2->GetArea()]++; } } @@ -570,6 +503,7 @@ void CheckTrackerLoadGame(int32_t fileNum) { initialized = true; UpdateAllOrdering(); UpdateInventoryChecks(); + UpdateFilters(); } void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) { @@ -581,10 +515,9 @@ void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) { if (GetCheckArea() == RCAREA_KAKARIKO_VILLAGE && gPlayState->sceneNum == SCENE_BAZAAR) { slot = RC_KAK_BAZAAR_ITEM_1 + cursorSlot; } - auto status = gSaveContext.checkTrackerData[slot].status; + auto status = OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->GetCheckStatus(); if (status == RCSHOW_SEEN) { - gSaveContext.checkTrackerData[slot].status = RCSHOW_IDENTIFIED; - gSaveContext.checkTrackerData[slot].price = basePrice; + OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->SetCheckStatus(RCSHOW_IDENTIFIED); SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); } } @@ -617,8 +550,7 @@ void CheckTrackerFrame() { return; } // TODO: Move to OnAmmoChange hook once it gets added. - if (gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_COLLECTED && - gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_SAVED) { + if (!OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->HasObtained()) { if (BEANS_BOUGHT >= 10) { SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN); } @@ -802,11 +734,7 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { } Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck(); SpoilerCollectionCheckType scCheckType = scCheck.type; - if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && - (scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_FISH || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD || - scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) { + if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF) { if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(loc.GetRandomizerCheck())) { SetCheckCollected(loc.GetRandomizerCheck()); return; @@ -827,33 +755,43 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; - for (auto& loc : Rando::StaticData::GetLocationTable()) { - if (loc.GetRandomizerCheck() != RC_UNKNOWN_CHECK && loc.GetRandomizerCheck() != RC_MAX) { - DefaultCheckData(loc.GetRandomizerCheck()); - } - } - UpdateAllOrdering(); } -void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) { - SaveManager::Instance->SaveArray("checks", ARRAY_COUNT(saveContext->checkTrackerData), [&](size_t i) { - if (saveContext->checkTrackerData[i].status == RCSHOW_COLLECTED) { - if (gameSave) { - gSaveContext.checkTrackerData[i].status = saveContext->checkTrackerData[i].status = RCSHOW_SAVED; - UpdateAllOrdering(); - UpdateInventoryChecks(); - } else { - saveContext->checkTrackerData[i].status = RCSHOW_SCUMMED; +void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { + bool updateOrdering = false; + std::vector checkCount; + for (int i = RC_UNKNOWN_CHECK; i < RC_MAX; i++) { + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetCheckStatus() != RCSHOW_UNCHECKED || + OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetIsSkipped()) + checkCount.push_back(static_cast(i)); + } + SaveManager::Instance->SaveArray("checkStatus", checkCount.size(), [&](size_t i) { + RandomizerCheck check = checkCount.at(i); + RandomizerCheckStatus savedStatus = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetCheckStatus(); + bool isSkipped = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetIsSkipped(); + if (savedStatus == RCSHOW_COLLECTED) { + if (fullSave) { + OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->SetCheckStatus(RCSHOW_SAVED); + savedStatus = RCSHOW_SAVED; + updateOrdering = true; + } + else { + savedStatus = RCSHOW_SCUMMED; } } - SaveManager::Instance->SaveStruct("", [&]() { - SaveManager::Instance->SaveData("status", saveContext->checkTrackerData[i].status); - SaveManager::Instance->SaveData("skipped", saveContext->checkTrackerData[i].skipped); - SaveManager::Instance->SaveData("price", saveContext->checkTrackerData[i].price); - SaveManager::Instance->SaveData("hintItem", saveContext->checkTrackerData[i].hintItem); - }); + if (savedStatus != RCSHOW_UNCHECKED || isSkipped) { + SaveManager::Instance->SaveStruct("", [&]() { + SaveManager::Instance->SaveData("randomizerCheck", check); + SaveManager::Instance->SaveData("status", savedStatus); + SaveManager::Instance->SaveData("skipped", isSkipped); + }); + } }); SaveManager::Instance->SaveData("areasSpoiled", areasSpoiled); + if (updateOrdering) { + UpdateAllOrdering(); + UpdateAllAreas(); + } } void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { @@ -861,15 +799,21 @@ void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { } void LoadFile() { - SaveManager::Instance->LoadArray("checks", RC_MAX, [](size_t i) { + SaveManager::Instance->LoadArray("checkStatus", RC_MAX, [](size_t i) { SaveManager::Instance->LoadStruct("", [&]() { - SaveManager::Instance->LoadData("status", gSaveContext.checkTrackerData[i].status); - SaveManager::Instance->LoadData("skipped", gSaveContext.checkTrackerData[i].skipped); - SaveManager::Instance->LoadData("price", gSaveContext.checkTrackerData[i].price); - SaveManager::Instance->LoadData("hintItem", gSaveContext.checkTrackerData[i].hintItem); + RandomizerCheckStatus status; + bool skipped; + RandomizerCheck rc; + SaveManager::Instance->LoadData("randomizerCheck", rc, RC_UNKNOWN_CHECK); + SaveManager::Instance->LoadData("status", status, RCSHOW_UNCHECKED); + SaveManager::Instance->LoadData("skipped", skipped, false); + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetCheckStatus(status); + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(skipped); + }); }); - }); - SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled); + SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled, (uint32_t)0); + UpdateAllOrdering(); + UpdateAllAreas(); } void Teardown() { @@ -877,6 +821,8 @@ void Teardown() { ClearAreaChecksAndTotals(); checksByArea.clear(); areasSpoiled = 0; + filterAreasHidden = { 0 }; + filterChecksHidden = { 0 }; lastLocationChecked = RC_UNKNOWN_CHECK; } @@ -890,24 +836,7 @@ void SetAreaSpoiled(RandomizerCheckArea rcArea) { SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); } -void UpdateCheck(uint32_t check, RandomizerCheckTrackerData data) { - auto area = Rando::StaticData::GetLocation(static_cast(check))->GetArea(); - if ((!gSaveContext.checkTrackerData[check].skipped && data.skipped) || - ((gSaveContext.checkTrackerData[check].status != RCSHOW_COLLECTED && gSaveContext.checkTrackerData[check].status != RCSHOW_SAVED) && - (data.status == RCSHOW_COLLECTED || data.status == RCSHOW_SAVED))) { - areaChecksGotten[area]++; - } else if ((gSaveContext.checkTrackerData[check].skipped && !data.skipped) || - ((gSaveContext.checkTrackerData[check].status == RCSHOW_COLLECTED || gSaveContext.checkTrackerData[check].status == RCSHOW_SAVED) && - (data.status != RCSHOW_COLLECTED && data.status != RCSHOW_SAVED))) { - areaChecksGotten[area]--; - } - gSaveContext.checkTrackerData[check] = data; - UpdateOrdering(area); -} - void CheckTrackerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver); - 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)) { return; @@ -918,14 +847,16 @@ void CheckTrackerWindow::DrawElement() { int comboButton2Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; OSContPad* trackerButtonsPressed = Ship::Context::GetInstance()->GetControlDeck()->GetPads(); bool comboButtonsHeld = trackerButtonsPressed != nullptr && - trackerButtonsPressed[0].button & comboButton1Mask && - trackerButtonsPressed[0].button & comboButton2Mask; + trackerButtonsPressed[0].button & comboButton1Mask && + trackerButtonsPressed[0].button & comboButton2Mask; if (!comboButtonsHeld) { return; } } } + ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver); + BeginFloatWindows("Check Tracker", mIsVisible, ImGuiWindowFlags_NoScrollbar); if (!GameInteractor::IsSaveLoaded() || !initialized) { @@ -952,7 +883,7 @@ void CheckTrackerWindow::DrawElement() { return; } - AreaTable_Init(); + RegionTable_Init(); ImGui::TableNextRow(0, headerHeight); ImGui::TableNextColumn(); @@ -976,7 +907,9 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = true; } UIWidgets::Tooltip("Clear the search field"); - checkSearch.Draw(); + if (checkSearch.Draw()) { + UpdateFilters(); + } UIWidgets::PaddedSeparator(); @@ -1030,7 +963,7 @@ void CheckTrackerWindow::DrawElement() { previousShowHidden = showHidden; doAreaScroll = true; } - if ((shouldHideFilteredAreas && ShouldHideArea(rcArea)) || + if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || (!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) ) { doDraw = false; @@ -1090,7 +1023,7 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = false; } for (auto rc : checks) { - if (doDraw && isThisAreaSpoiled && ShouldShowCheck(rc)) { + if (doDraw && isThisAreaSpoiled && !filterChecksHidden[rc]) { DrawLocation(rc); } } @@ -1110,13 +1043,16 @@ void CheckTrackerWindow::DrawElement() { } } -bool ShouldHideArea(RandomizerCheckArea rcArea) { - if (checkSearch.Filters.Size == 0 || checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) { - return false; - } - for (auto check : checksByArea[rcArea]) { - if (ShouldShowCheck(check)) { - return false; +bool UpdateFilters() { + for (auto& [rcArea, checks] : checksByArea) { + filterAreasHidden[rcArea] = !checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str()); + for (auto check : checks) { + if (ShouldShowCheck(check)) { + filterAreasHidden[rcArea] = false; + filterChecksHidden[check] = false; + } else { + filterChecksHidden[check] = true; + } } } @@ -1127,8 +1063,9 @@ bool ShouldShowCheck(RandomizerCheck check) { return ( IsVisibleInCheckTracker(check) && (checkSearch.Filters.Size == 0 || - checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea()).c_str()) || - checkSearch.PassFilter(Rando::StaticData::GetLocation(check)->GetShortName().c_str())) + checkSearch.PassFilter((Rando::StaticData::GetLocation(check)->GetShortName() + " " + + Rando::StaticData::GetLocation(check)->GetName() + " " + + RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())).c_str())) ); } @@ -1164,12 +1101,11 @@ void EndFloatWindows() { } void LoadSettings() { - //If in randomzer (n64ddFlag), then get the setting and check if in general we should be showing the settings + //If in randomzer, then get the setting and check if in general we should be showing the settings //If in vanilla, _try_ to show items that at least are needed for 100% - showShops = IS_RANDO ? ( - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_ZERO_ITEMS) + showShops = IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF : false; showBeans = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAGIC_BEANS) == RO_GENERIC_YES @@ -1284,6 +1220,7 @@ 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 (rc != RC_LINKS_POCKET || showLinksPocket) && @@ -1321,7 +1258,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && (rc != RC_HC_MALON_EGG || showWeirdEgg) && (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && - (loc->GetRCType() != RCTYPE_MAP_COMPASS || showStartingMapsCompasses) && + ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && @@ -1359,6 +1296,13 @@ void UpdateInventoryChecks() { void UpdateAreaFullyChecked(RandomizerCheckArea area) { } +void UpdateAllAreas() { + // Sort the entire thing + for (int i = 0; i < RCAREA_INVALID; i++) { + UpdateAreas(static_cast(i)); + } +} + void UpdateAreas(RandomizerCheckArea area) { areasFullyChecked[area] = areaChecksGotten[area] == checksByArea.find(area)->second.size(); } @@ -1375,7 +1319,7 @@ void UpdateOrdering(RandomizerCheckArea rcArea) { if(checksByArea.contains(rcArea)) { std::sort(checksByArea.find(rcArea)->second.begin(), checksByArea.find(rcArea)->second.end(), CompareChecks); } - + RecalculateAllAreaTotals(); CalculateTotals(); } @@ -1384,14 +1328,14 @@ bool IsEoDCheck(RandomizerCheckType type) { } bool CompareChecks(RandomizerCheck i, RandomizerCheck j) { - RandomizerCheckTrackerData iShow = gSaveContext.checkTrackerData[i]; - RandomizerCheckTrackerData jShow = gSaveContext.checkTrackerData[j]; Rando::Location* x = Rando::StaticData::GetLocation(i); Rando::Location* y = Rando::StaticData::GetLocation(j); - bool iCollected = iShow.status == RCSHOW_COLLECTED || iShow.status == RCSHOW_SAVED; - bool iSaved = iShow.status == RCSHOW_SAVED; - bool jCollected = jShow.status == RCSHOW_COLLECTED || jShow.status == RCSHOW_SAVED; - bool jSaved = jShow.status == RCSHOW_SAVED; + auto itemI = OTRGlobals::Instance->gRandoContext->GetItemLocation(i); + auto itemJ = OTRGlobals::Instance->gRandoContext->GetItemLocation(j); + bool iCollected = itemI->HasObtained(); + bool iSaved = itemI->GetCheckStatus() == RCSHOW_SAVED; + bool jCollected = itemJ->HasObtained(); + bool jSaved = itemJ->GetCheckStatus() == RCSHOW_SAVED; if (!iCollected && jCollected) { return true; @@ -1405,9 +1349,9 @@ bool CompareChecks(RandomizerCheck i, RandomizerCheck j) { return false; } - if (!iShow.skipped && jShow.skipped) { + if (!itemI->GetIsSkipped() && itemJ->GetIsSkipped()) { return true; - } else if (iShow.skipped && !jShow.skipped) { + } else if (itemI->GetIsSkipped() && !itemJ->GetIsSkipped()) { return false; } @@ -1437,14 +1381,8 @@ void DrawLocation(RandomizerCheck rc) { bool showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); Rando::Location* loc = Rando::StaticData::GetLocation(rc); Rando::ItemLocation* itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); - RandomizerCheckTrackerData checkData = gSaveContext.checkTrackerData[rc]; - RandomizerCheckStatus status = checkData.status; - - if (itemLoc->HasObtained()) { - status = RCSHOW_COLLECTED; - } - - bool skipped = checkData.skipped; + RandomizerCheckStatus status = itemLoc->GetCheckStatus(); + bool skipped = itemLoc->GetIsSkipped(); if (status == RCSHOW_COLLECTED) { if (!showHidden && CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0)) { return; @@ -1516,11 +1454,13 @@ void DrawLocation(RandomizerCheck rc) { if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED || skipped) { if (UIWidgets::StateButton(std::to_string(rc).c_str(), skipped ? ICON_FA_PLUS : ICON_FA_TIMES)) { if (skipped) { - gSaveContext.checkTrackerData[rc].skipped = false; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); areaChecksGotten[loc->GetArea()]--; + totalChecksGotten--; } else { - gSaveContext.checkTrackerData[rc].skipped = true; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(true); areaChecksGotten[loc->GetArea()]++; + totalChecksGotten++; } UpdateOrdering(loc->GetArea()); UpdateInventoryChecks(); @@ -1541,9 +1481,7 @@ void DrawLocation(RandomizerCheck rc) { bool mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && itemLoc->IsAddedToPool(); - if (checkData.hintItem != 0) { - // TODO hints - } else if (status != RCSHOW_UNCHECKED) { + if (status != RCSHOW_UNCHECKED) { switch (status) { case RCSHOW_SAVED: case RCSHOW_COLLECTED: @@ -1572,8 +1510,8 @@ void DrawLocation(RandomizerCheck rc) { } else if (!mystery) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } - if (!IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { - txt += fmt::format(" - {}", gSaveContext.checkTrackerData[rc].price); + if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { + txt += fmt::format(" - {}", OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice()); } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { @@ -1599,8 +1537,7 @@ void DrawLocation(RandomizerCheck rc) { } if (CVarGetInteger("gCheckTrackerOptionShowLogic", 0)) { - std::vector locationsInRegion = areaTable[itemLoc->GetParentRegionKey()].locations; - for (auto& locationInRegion : locationsInRegion) { + for (auto& locationInRegion : areaTable[itemLoc->GetParentRegionKey()].locations) { if (locationInRegion.GetLocation() == rc) { std::string conditionStr = locationInRegion.GetConditionStr(); if (conditionStr != "true") { @@ -1700,14 +1637,8 @@ static const char* windowType[] = { "Floating", "Window" }; static const char* displayType[] = { "Always", "Combo Button Hold" }; static const char* buttonStrings[] = { "A Button", "B Button", "C-Up", "C-Down", "C-Left", "C-Right", "L Button", "Z Button", "R Button", "Start", "D-Up", "D-Down", "D-Left", "D-Right" }; -void CheckTrackerSettingsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin("Check Tracker Settings", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } +void CheckTrackerSettingsWindow::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); ImGui::BeginTable("CheckTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV); ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); @@ -1739,12 +1670,12 @@ void CheckTrackerSettingsWindow::DrawElement() { UIWidgets::Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. Otherwise, Vanilla/MQ dungeon locations must be unlocked."); if (UIWidgets::EnhancementCheckbox("Hide right-side shop item checks", CVAR_TRACKER_CHECK("HideRightShopChecks"), false, "", UIWidgets::CheckboxGraphics::Cross, true)) { hideShopRightChecks = !hideShopRightChecks; - RecalculateAreaTotals(); + RecalculateAllAreaTotals(); } UIWidgets::Tooltip("If enabled, will prevent the tracker from displaying slots 1-4 in all shops."); if (UIWidgets::EnhancementCheckbox("Always show gold skulltulas", CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), false, "")) { alwaysShowGS = !alwaysShowGS; - RecalculateAreaTotals(); + RecalculateAllAreaTotals(); } UIWidgets::Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings."); UIWidgets::EnhancementCheckbox("Show Logic", "gCheckTrackerOptionShowLogic"); @@ -1769,7 +1700,6 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::PopStyleVar(1); ImGui::EndTable(); - ImGui::End(); } void CheckTrackerWindow::InitElement() { @@ -1794,7 +1724,7 @@ void CheckTrackerWindow::InitElement() { Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor"), Color_Saved_Extra_Default); SaveManager::Instance->AddInitFunction(InitTrackerData); - sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, -1); + sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, SECTION_PARENT_NONE); SaveManager::Instance->AddLoadFunction("trackerData", 1, LoadFile); GameInteractor::Instance->RegisterGameHook(CheckTrackerLoadGame); GameInteractor::Instance->RegisterGameHook([](uint32_t fileNum) { @@ -1809,8 +1739,6 @@ void CheckTrackerWindow::InitElement() { hideShopRightChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideRightShopChecks"), 1); alwaysShowGS = CVarGetInteger(CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), 0); - - //LocationTable_Init(); } } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 60094dd0213..3d3330f218f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -43,20 +43,19 @@ class CheckTrackerWindow : public Ship::GuiWindow { //repeat... #define INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(idx) (0x8000 >> (7 - (idx % 8) + ((idx % 16) / 8) * 8)) -void DefaultCheckData(RandomizerCheck rc); void Teardown(); void UpdateAllOrdering(); bool IsVisibleInCheckTracker(RandomizerCheck rc); bool IsCheckShuffled(RandomizerCheck rc); void InitTrackerData(bool isDebug); RandomizerCheckArea GetCheckArea(); -void UpdateCheck(uint32_t, RandomizerCheckTrackerData); uint16_t GetTotalChecks(); uint16_t GetTotalChecksGotten(); bool IsAreaSpoiled(RandomizerCheckArea rcArea); void SetAreaSpoiled(RandomizerCheckArea rcArea); +void UpdateInventoryChecks(); +void UpdateAreas(RandomizerCheckArea area); +void UpdateAllOrdering(); +void UpdateAllAreas(); +void RecalculateAllAreaTotals(); } // namespace CheckTracker - - -void to_json(nlohmann::json & j, const RandomizerCheckTrackerData& rctd); -void from_json(const nlohmann::json& j, RandomizerCheckTrackerData& rctd); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 851bdf2d26b..4cf9d623aad 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -640,13 +640,6 @@ void InitEntranceTrackingData() { } void EntranceTrackerSettingsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin("Entrance Tracker Settings", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - if (ImGui::BeginTable("entranceTrackerSettings", 1, ImGuiTableFlags_BordersInnerH)) { ImGui::TableNextColumn(); @@ -718,8 +711,15 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::EndTable(); } +} - ImGui::End(); +void EntranceTrackerWindow::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); } void EntranceTrackerWindow::DrawElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h index 22e27a2501c..6e6a35ed64a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h @@ -99,6 +99,7 @@ class EntranceTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; + void Draw() override; void InitElement() override; void DrawElement() override; void UpdateElement() override {}; diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 8b7f97a69c7..2b67e105d50 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -390,7 +390,13 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { case ITEM_WALLET_ADULT: case ITEM_WALLET_GIANT: result.currentCapacity = IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); - result.maxCapacity = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS ? 999 : 500; + result.maxCapacity = !IS_RANDO || ( + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF || + ( + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS + ) + ) ? 500 : 999; result.currentAmmo = gSaveContext.rupees; break; case ITEM_BOMBCHU: @@ -1206,6 +1212,15 @@ void ItemTrackerLoadFile() { } } +void ItemTrackerWindow::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); +} + void ItemTrackerWindow::DrawElement() { UpdateVectors(); @@ -1350,13 +1365,6 @@ static const char* extendedDisplayTypes[4] = { "Hidden", "Main Window", "Misc Wi static const char* minimalDisplayTypes[2] = { "Hidden", "Separate" }; void ItemTrackerSettingsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(733, 472), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin("Item Tracker Settings", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV); ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); @@ -1499,8 +1507,6 @@ void ItemTrackerSettingsWindow::DrawElement() { ImGui::PopStyleVar(1); ImGui::EndTable(); - - ImGui::End(); } void ItemTrackerWindow::InitElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h index 3fba1cf939e..5405b1ea2ad 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h @@ -47,6 +47,7 @@ class ItemTrackerSettingsWindow : public Ship::GuiWindow { class ItemTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; + void Draw() override; protected: void InitElement() override; diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 8859e8d43cb..bab0b4e41b2 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -97,7 +97,7 @@ void GiveLinksPocketItem() { if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, (GetItemID)RG_NONE); StartingItemGive(getItemEntry); - Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->MarkAsObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->SetCheckStatus(RCSHOW_SAVED); // If we re-add the above, we'll get the item on save creation, now it's given on first load Flags_SetRandomizerInf(RAND_INF_LINKS_POCKET); } @@ -327,6 +327,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_FISHING_POLE) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); + } + // Give Link's pocket item GiveLinksPocketItem(); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index f3f860800bc..4ecdd5b1835 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -36,7 +36,7 @@ std::vector MultiVecOpts(const std::vector return options; } -Settings::Settings() : mExcludeLocationsOptionsGroups(SPOILER_COLLECTION_GROUP_COUNT) { +Settings::Settings() : mExcludeLocationsOptionsAreas(RCAREA_INVALID) { } void Settings::CreateOptions() { @@ -97,7 +97,8 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_DUNGEON_REWARDS] = Option::U8("Shuffle Dungeon Rewards", {"End of Dungeons", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WidgetType::Combobox, RO_DUNGEON_REWARDS_END_OF_DUNGEON); mOptions[RSK_LINKS_POCKET] = Option::U8("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), "", WidgetType::Combobox, RO_LINKS_POCKET_DUNGEON_REWARD); mOptions[RSK_SHUFFLE_SONGS] = Option::U8("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WidgetType::Combobox, RO_SONG_SHUFFLE_SONG_LOCATIONS); - mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "0 Items", "1 Item", "2 Items", "3 Items", "4 Items", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); + mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); + mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shopsanity Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shopsanity Prices", {"Balanced", "Starting Wallet", "Adult Wallet", "Giant's Wallet", "Tycoon's Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_SHOPSANITY_PRICE_BALANCED, false, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); @@ -129,7 +130,7 @@ void Settings::CreateOptions() { mOptions[RSK_KEYSANITY] = Option::U8("Small Keys", {"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); mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); - mOptions[RSK_GANONS_BOSS_KEY] = Option::U8("Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "Triforce Hunt"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA); + mOptions[RSK_GANONS_BOSS_KEY] = Option::U8("Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward", "Triforce Hunt"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA); mOptions[RSK_LACS_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true); mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true); mOptions[RSK_LACS_REWARD_COUNT] = Option::U8("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); @@ -217,7 +218,7 @@ void Settings::CreateOptions() { mOptions[RSK_DAMAGE_MULTIPLIER] = Option::U8("Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT); // clang-format on - mExcludeLocationsOptionsGroups.reserve(SPOILER_COLLECTION_GROUP_COUNT); + mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); mTrickOptions[RT_ACUTE_ANGLE_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."); mTrickOptions[RT_ADVANCED_CLIPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."); @@ -672,6 +673,7 @@ void Settings::CreateOptions() { }, false, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { &mOptions[RSK_SHOPSANITY], + &mOptions[RSK_SHOPSANITY_COUNT], &mOptions[RSK_SHOPSANITY_PRICES], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], &mOptions[RSK_FISHSANITY], @@ -876,6 +878,7 @@ void Settings::CreateOptions() { &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHOPSANITY], + &mOptions[RSK_SHOPSANITY_COUNT], &mOptions[RSK_SHOPSANITY_PRICES], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], &mOptions[RSK_FISHSANITY], @@ -1007,44 +1010,56 @@ void Settings::CreateOptions() { &mOptions[RSK_ICE_TRAPS] })); // TODO: Progressive Goron Sword, Remove Double Defense - mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsGroups[GROUP_KOKIRI_FOREST], false); - mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsGroups[GROUP_LOST_WOODS], false); - mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_DEKU_TREE], false); - mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_FOREST_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsGroups[GROUP_KAKARIKO], false); - mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_BOTTOM_OF_THE_WELL], false); - mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_SHADOW_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN] = OptionGroup::SubGroup("Death Mountain", mExcludeLocationsOptionsGroups[GROUP_DEATH_MOUNTAIN], false); - mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsGroups[GROUP_GORON_CITY], false); - mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_DODONGOS_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_FIRE_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsGroups[GROUP_ZORAS_RIVER], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsGroups[GROUP_ZORAS_DOMAIN], false); - mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_JABUJABUS_BELLY], false); - mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_ICE_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsGroups[GROUP_HYRULE_FIELD], false); - mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsGroups[GROUP_LON_LON_RANCH], false); - mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsGroups[GROUP_LAKE_HYLIA], false); - mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_WATER_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsGroups[GROUP_GERUDO_VALLEY], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS] = OptionGroup::SubGroup("Gerudo Training Grounds", mExcludeLocationsOptionsGroups[GROUP_GERUDO_TRAINING_GROUND], false); - mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_SPIRIT_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsGroups[GROUP_HYRULE_CASTLE], false); - mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsGroups[GROUP_DUNGEON_GANONS_CASTLE], false); + mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST], false); + mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS], false); + mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW], false); + mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE], false); + mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE], false); + mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE], false); + mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD], false); + mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL], false); + mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE], false); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL], false); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER], false); + mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY], false); + mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN], false); + mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE], false); + mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER], false); + mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN], false); + mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN], false); + mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY], false); + mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN], false); + mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD], false); + mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH], false); + mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA], false); + mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE], false); + mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY], false); + mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS], false); + mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND], false); + mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS], false); + mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS] = OptionGroup::SubGroup("Gerudo Training Grounds", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND], false); + mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE], false); + mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE], false); + mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET], false); + mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE], false); mOptionGroups[RSG_EXCLUDES] = OptionGroup::SubGroup("Exclude Locations", { &mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST], &mOptionGroups[RSG_EXCLUDES_LOST_WOODS], + &mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW], &mOptionGroups[RSG_EXCLUDES_DEKU_TREE], &mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE], &mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE], + &mOptionGroups[RSG_EXCLUDES_GRAVEYARD], &mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL], &mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN], + &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL], + &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER], &mOptionGroups[RSG_EXCLUDES_GORON_CITY], &mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN], &mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE], &mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER], &mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN], + &mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN], &mOptionGroups[RSG_EXCLUDES_JABU_JABU], &mOptionGroups[RSG_EXCLUDES_ICE_CAVERN], &mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD], @@ -1052,9 +1067,13 @@ void Settings::CreateOptions() { &mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA], &mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE], &mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY], + &mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS], + &mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND], + &mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS], &mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS], &mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE], &mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE], + &mOptionGroups[RSG_EXCLUDES_MARKET], &mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE], }, false); mOptionGroups[RSG_DETAILED_LOGIC] = OptionGroup("Detailed Logic Settings", { @@ -1068,6 +1087,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], &mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHOPSANITY], + &mOptions[RSK_SHOPSANITY_COUNT], &mOptions[RSK_SHOPSANITY_PRICES], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], &mOptions[RSK_FISHSANITY], @@ -1109,6 +1129,7 @@ void Settings::CreateOptions() { { "Shuffle Settings:Shuffle Songs", RSK_SHUFFLE_SONGS }, { "Shuffle Settings:Shuffle Gerudo Membership Card", RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD }, { "Shuffle Settings:Shopsanity", RSK_SHOPSANITY }, + { "Shuffle Settings:Shopsanity Specific Count", RSK_SHOPSANITY_COUNT }, { "Shuffle Settings:Shopsanity Prices", RSK_SHOPSANITY_PRICES }, { "Shuffle Settings:Affordable Prices", RSK_SHOPSANITY_PRICES_AFFORDABLE }, { "Shuffle Settings:Fishsanity", RSK_FISHSANITY }, @@ -1267,12 +1288,12 @@ const std::array& Settings::GetAllOptions() const { return mOptions; } -std::vector