From 01245ae81ce2752b3c74f66b60a135d00ee70d26 Mon Sep 17 00:00:00 2001 From: Archez Date: Sun, 18 Aug 2024 15:25:21 -0400 Subject: [PATCH 01/43] Bump LUS (#4301) * bump lus * remove undeclared methods --- libultraship | 2 +- soh/soh/Enhancements/controls/InputViewer.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/libultraship b/libultraship index 31e9b009f94..92bce011545 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 31e9b009f94e7074a847c7954926cba354cd7c72 +Subproject commit 92bce01154589080e534c3c143913a196e161f02 diff --git a/soh/soh/Enhancements/controls/InputViewer.h b/soh/soh/Enhancements/controls/InputViewer.h index 3e1e9c98798..b4d6413e16a 100644 --- a/soh/soh/Enhancements/controls/InputViewer.h +++ b/soh/soh/Enhancements/controls/InputViewer.h @@ -28,8 +28,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 +42,4 @@ class InputViewerSettingsWindow : public Ship::GuiWindow { InputViewerSettingsWindow(); ~InputViewerSettingsWindow(); - - void Draw(); }; From e07fc59e55bf8041f0c752708acf0f8851b1d9aa Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:17:45 +0200 Subject: [PATCH 02/43] Add git info to title screen & gameplay stats (#4053) * Add git info to title screen & gameplay stats * Change the branch criteria to starting with `develop` * Update z_title.c * Change the branch criteria to not having a tag * Always show both when not a release build * Only show build version in tagged releases --- CMakeLists.txt | 31 +++++++++++++++++++ soh/include/variables.h | 5 ++- soh/soh/CrashHandlerExt.cpp | 2 ++ soh/soh/Enhancements/gameplaystats.cpp | 8 ++++- .../randomizer/3drando/spoiler_log.cpp | 2 ++ soh/soh/OTRGlobals.cpp | 2 +- soh/src/boot/build.c.in | 4 +++ .../overlays/gamestates/ovl_title/z_title.c | 21 +++++++++++-- 8 files changed, 70 insertions(+), 5 deletions(-) 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/soh/include/variables.h b/soh/include/variables.h index 2c226f2c6b9..692d1b2f82e 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/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/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 61eb88a6f16..93cb672e3f3 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 { diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 23599627336..d03c735e6c2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -864,6 +864,8 @@ const char* SpoilerLog_Write(int language) { jsonData.clear(); jsonData["version"] = (char*) gBuildVersion; + jsonData["git_branch"] = (char*) gGitBranch; + jsonData["git_commit"] = (char*) gGitCommitHash; jsonData["seed"] = Settings::seedString; jsonData["finalSeed"] = Settings::seed; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 456e07eaa0c..6e41eb7a8a8 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -340,7 +340,7 @@ OTRGlobals::OTRGlobals() { context->InitAudio(); - SPDLOG_INFO("Starting Ship of Harkinian version {}", (char*)gBuildVersion); + SPDLOG_INFO("Starting Ship of Harkinian version {} (Branch: {} | Commit: {})", (char*)gBuildVersion, (char*)gGitBranch, (char*)gGitCommitHash); auto loader = context->GetResourceManager()->GetResourceLoader(); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Texture", static_cast(LUS::ResourceType::Texture), 0); diff --git a/soh/src/boot/build.c.in b/soh/src/boot/build.c.in index 4d6a07ce66b..4467d04c819 100644 --- a/soh/src/boot/build.c.in +++ b/soh/src/boot/build.c.in @@ -5,6 +5,10 @@ const u16 gBuildVersionMajor = @CMAKE_PROJECT_VERSION_MAJOR@; const u16 gBuildVersionMinor = @CMAKE_PROJECT_VERSION_MINOR@; const u16 gBuildVersionPatch = @CMAKE_PROJECT_VERSION_PATCH@; +const char gGitBranch[] = "@CMAKE_PROJECT_GIT_BRANCH@"; +const char gGitCommitHash[] = "@CMAKE_PROJECT_GIT_COMMIT_HASH@"; +const char gGitCommitTag[] = "@CMAKE_PROJECT_GIT_COMMIT_TAG@"; + const char gBuildTeam[] = "@PROJECT_TEAM@"; const char gBuildDate[] = __DATE__ " " __TIME__; const char gBuildMakeOption[] = ""; diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 51d0ac62b3a..8893d9d5f5c 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "time.h" @@ -30,8 +31,24 @@ void Title_PrintBuildInfo(Gfx** gfxp) { GfxPrint_Open(&printer, g); GfxPrint_SetColor(&printer, 131, 154, 255, 255); - GfxPrint_SetPos(&printer, 1, 25); - GfxPrint_Printf(&printer, "%s", gBuildVersion); + //if tag is empty (not a release build) + bool showGitInfo = gGitCommitTag[0] == 0; + + if (showGitInfo) { + GfxPrint_SetPos(&printer, 1, 24); + GfxPrint_Printf(&printer, "Git Branch: %s", gGitBranch); + + //truncate the commit to 7 characters + char gGitCommitHashTruncated[8]; + strncpy(gGitCommitHashTruncated, gGitCommitHash, 7); + gGitCommitHashTruncated[7] = 0; + + GfxPrint_SetPos(&printer, 1, 25); + GfxPrint_Printf(&printer, "Git Commit: %s", gGitCommitHashTruncated); + } else { + GfxPrint_SetPos(&printer, 1, 25); + GfxPrint_Printf(&printer, "%s", gBuildVersion); + } GfxPrint_SetPos(&printer, 1, 26); GfxPrint_Printf(&printer, "%s", gBuildDate); From 48663d74ac50fbe941986e21fa3aae4c74047e11 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Fri, 30 Aug 2024 08:28:09 -0700 Subject: [PATCH 03/43] Change Recommended VS build tools from 142 to 143 (#4315) * Changed references for VS build tools 142 to 143 to reflect current state of development. * Remove VS 2019. --- docs/BUILDING.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) 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 From b5037a0856032d9f7a5b5b852c2dff0e510d793d Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 10 Sep 2024 12:42:57 -0700 Subject: [PATCH 04/43] Gui window rework (#4307) * Converted all GuiWindows to the new separate Begin/End format in current LUS except InputViewer, CheckTracker, ItemTracker and Modals. * Setup Check, Entrance, Item trackers and Input Viewer to override `Draw()` to bypass the ImGui Begin and End, as they're not intended to go in the modern menu. * Cleanup. --- soh/soh/Enhancements/audio/AudioEditor.cpp | 7 - soh/soh/Enhancements/controls/InputViewer.cpp | 656 ++++++++-------- soh/soh/Enhancements/controls/InputViewer.h | 1 + .../cosmetics/CosmeticsEditor.cpp | 7 - .../Enhancements/debugger/MessageViewer.cpp | 6 - soh/soh/Enhancements/debugger/actorViewer.cpp | 8 - soh/soh/Enhancements/debugger/colViewer.cpp | 7 - .../Enhancements/debugger/debugSaveEditor.cpp | 8 - soh/soh/Enhancements/debugger/dlViewer.cpp | 11 - soh/soh/Enhancements/debugger/valueViewer.cpp | 8 - soh/soh/Enhancements/gameplaystats.cpp | 8 - .../Enhancements/randomizer/randomizer.cpp | 8 - .../randomizer/randomizer_check_tracker.cpp | 26 +- .../randomizer/randomizer_check_tracker.h | 1 + .../randomizer_entrance_tracker.cpp | 11 +- .../randomizer/randomizer_entrance_tracker.h | 1 + .../randomizer/randomizer_item_tracker.cpp | 18 +- .../randomizer/randomizer_item_tracker.h | 1 + .../resolution-editor/ResolutionEditor.cpp | 718 +++++++++--------- soh/soh/SohGui.cpp | 28 +- soh/soh/SohModals.cpp | 9 + soh/soh/SohModals.h | 1 + 22 files changed, 748 insertions(+), 801 deletions(-) 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 b4d6413e16a..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 {}; diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 4badd827973..b0e81c16ca4 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1687,12 +1687,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); @@ -1811,7 +1805,6 @@ void CosmeticsEditorWindow::DrawElement() { } ImGui::EndTabBar(); } - ImGui::End(); } void RegisterOnLoadGameHook() { diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index a9a6b613e91..46c596e9c37 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 daf08894251..a29174331a9 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1747,12 +1747,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(); @@ -1786,8 +1780,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/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index 97bf8516403..c2b27c79dc0 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -102,12 +102,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(); @@ -212,8 +206,6 @@ void ValueViewerWindow::DrawElement() { } ImGui::EndGroup(); } - - ImGui::End(); } void ValueViewerWindow::InitElement() { diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 93cb672e3f3..82a4b3b6e17 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -625,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)) { @@ -654,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/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5ea7293eb38..487348c9db7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3137,13 +3137,6 @@ void RandomizerSettingsWindow::DrawElement() { static int maxKeyringCount; static bool disableGFKeyring = false; - - 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); @@ -5284,7 +5277,6 @@ void RandomizerSettingsWindow::DrawElement() { if (disableEditingRandoSettings) { UIWidgets::ReEnableComponent(""); } - ImGui::End(); } CustomMessage Randomizer::GetWarpSongMessage(u16 textId, bool mysterious) { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 02952a05278..508cc5e425e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -867,9 +867,16 @@ void UpdateCheck(uint32_t check, RandomizerCheckTrackerData data) { UpdateOrdering(area); } -void CheckTrackerWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver); +void CheckTrackerWindow::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); +} +void CheckTrackerWindow::DrawElement() { 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; @@ -880,14 +887,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) { @@ -1601,14 +1610,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); @@ -1668,7 +1671,6 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::PopStyleVar(1); ImGui::EndTable(); - ImGui::End(); } void CheckTrackerWindow::InitElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index be1ae441c0d..b1fab2a21eb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -21,6 +21,7 @@ class CheckTrackerSettingsWindow : public Ship::GuiWindow { class CheckTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; + void Draw() override; ~CheckTrackerWindow() {}; protected: diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 31d92165708..dbf06f4ce5c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -636,7 +636,17 @@ void InitEntranceTrackingData() { SortEntranceListByType(destListSortedByType, 1); } +void EntranceTrackerWindow::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); +} + void EntranceTrackerWindow::DrawElement() { + // Begin tracker settings ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Entrance Tracker", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { @@ -644,7 +654,6 @@ void EntranceTrackerWindow::DrawElement() { return; } - // Begin tracker settings ImGui::SetNextItemOpen(false, ImGuiCond_Once); if (ImGui::TreeNode("Tracker Settings")) { // Reduce indentation from the tree node for the table diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h index 87d73605833..e20aef76fa3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h @@ -89,6 +89,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 5fd158d8f66..98633d597f0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -1006,6 +1006,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(); @@ -1122,13 +1131,6 @@ static const char* displayTypes[3] = { "Hidden", "Main Window", "Separate" }; static const char* extendedDisplayTypes[4] = { "Hidden", "Main Window", "Misc Window", "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); @@ -1255,8 +1257,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 cae869c5438..3293912594c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h @@ -42,6 +42,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/resolution-editor/ResolutionEditor.cpp b/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp index f7eea08737b..21d99194ef7 100644 --- a/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp +++ b/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp @@ -59,424 +59,420 @@ void AdvancedResolutionSettingsWindow::InitElement() { } void AdvancedResolutionSettingsWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(497, 599), ImGuiCond_FirstUseEver); - if (ImGui::Begin("Advanced Resolution Settings", &mIsVisible)) { - // Initialise update flags. - bool update[3]; - for (uint8_t i = 0; i < sizeof(update); i++) - update[i] = false; - - // Initialise integer scale bounds. - short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get - // overridden depending on viewport res - - short integerScale_maximumBounds = 1; // can change when window is resized - // This is mostly just for UX purposes, as Fit Automatically logic is part of LUS. - if (((float)gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) > - ((float)gfx_current_dimensions.width / gfx_current_dimensions.height)) { - // Scale to window height - integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_dimensions.height; - } else { - // Scale to window width - integerScale_maximumBounds = gfx_current_game_window_viewport.width / gfx_current_dimensions.width; - } - // Lower-clamping maximum bounds value to 1 is no-longer necessary as that's accounted for in LUS. - // Letting it go below 1 in this Editor will even allow for checking if screen bounds are being exceeded. - if (default_maxIntegerScaleFactor < integerScale_maximumBounds) { - max_integerScaleFactor = - integerScale_maximumBounds + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); - } + // Initialise update flags. + bool update[3]; + for (uint8_t i = 0; i < sizeof(update); i++) + update[i] = false; + + // Initialise integer scale bounds. + short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get + // overridden depending on viewport res + + short integerScale_maximumBounds = 1; // can change when window is resized + // This is mostly just for UX purposes, as Fit Automatically logic is part of LUS. + if (((float)gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) > + ((float)gfx_current_dimensions.width / gfx_current_dimensions.height)) { + // Scale to window height + integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_dimensions.height; + } else { + // Scale to window width + integerScale_maximumBounds = gfx_current_game_window_viewport.width / gfx_current_dimensions.width; + } + // Lower-clamping maximum bounds value to 1 is no-longer necessary as that's accounted for in LUS. + // Letting it go below 1 in this Editor will even allow for checking if screen bounds are being exceeded. + if (default_maxIntegerScaleFactor < integerScale_maximumBounds) { + max_integerScaleFactor = + integerScale_maximumBounds + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); + } - // Combo List defaults - static int item_aspectRatio = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", 3); - static int item_pixelCount = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", default_pixelCount); - // Stored Values for non-UIWidgets elements - static float aspectRatioX = - CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioPresetsX[item_aspectRatio]); - static float aspectRatioY = - CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioPresetsY[item_aspectRatio]); - static int verticalPixelCount = - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", pixelCountPresets[item_pixelCount]); - // Additional settings - static bool showHorizontalResField = false; - static int horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - // Disabling flags - const bool disabled_everything = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); - const bool disabled_pixelCount = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0); + // Combo List defaults + static int item_aspectRatio = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", 3); + static int item_pixelCount = CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", default_pixelCount); + // Stored Values for non-UIWidgets elements + static float aspectRatioX = + CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioPresetsX[item_aspectRatio]); + static float aspectRatioY = + CVarGetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioPresetsY[item_aspectRatio]); + static int verticalPixelCount = + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", pixelCountPresets[item_pixelCount]); + // Additional settings + static bool showHorizontalResField = false; + static int horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; + // Disabling flags + const bool disabled_everything = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); + const bool disabled_pixelCount = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0); #ifdef __APPLE__ - // Display HiDPI warning. (Remove this once we can definitively say it's fixed.) - ImGui::TextColored(messageColor[MESSAGE_INFO], - ICON_FA_INFO_CIRCLE " These settings may behave incorrectly on Retina displays."); - UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + // Display HiDPI warning. (Remove this once we can definitively say it's fixed.) + ImGui::TextColored(messageColor[MESSAGE_INFO], + ICON_FA_INFO_CIRCLE " These settings may behave incorrectly on Retina displays."); + UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); #endif - if (ImGui::CollapsingHeader("Original Settings", ImGuiTreeNodeFlags_DefaultOpen)) { - // The original resolution slider (for convenience) - const bool disabled_resolutionSlider = (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0) && - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0)) || - CVarGetInteger(CVAR_LOW_RES_MODE, 0); - if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %.1f%%", "##IMul", CVAR_INTERNAL_RESOLUTION, 0.5f, - 2.0f, "", 1.0f, true, true, disabled_resolutionSlider)) { - Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier( - CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); - } - UIWidgets::Tooltip("Multiplies your output resolution by the value entered."); + if (ImGui::CollapsingHeader("Original Settings", ImGuiTreeNodeFlags_DefaultOpen)) { + // The original resolution slider (for convenience) + const bool disabled_resolutionSlider = (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0) && + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0)) || + CVarGetInteger(CVAR_LOW_RES_MODE, 0); + if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %.1f%%", "##IMul", CVAR_INTERNAL_RESOLUTION, 0.5f, + 2.0f, "", 1.0f, true, true, disabled_resolutionSlider)) { + Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier( + CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); + } + UIWidgets::Tooltip("Multiplies your output resolution by the value entered."); - // The original MSAA slider (also for convenience) + // The original MSAA slider (also for convenience) #ifndef __WIIU__ - if (UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", CVAR_MSAA_VALUE, 1, 8, "", 1, true, true, - false)) { - Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); - }; - UIWidgets::Tooltip( - "Activates multi-sample anti-aliasing when above 1x, up to 8x for 8 samples for every pixel.\n\n" - " " ICON_FA_INFO_CIRCLE - " (Higher MSAA with low resolution can approximate an authentic \"real N64\" look!)"); + if (UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", CVAR_MSAA_VALUE, 1, 8, "", 1, true, true, + false)) { + Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); + }; + UIWidgets::Tooltip( + "Activates multi-sample anti-aliasing when above 1x, up to 8x for 8 samples for every pixel.\n\n" + " " ICON_FA_INFO_CIRCLE + " (Higher MSAA with low resolution can approximate an authentic \"real N64\" look!)"); #endif - // N64 Mode toggle (again for convenience) - // UIWidgets::PaddedEnhancementCheckbox("(Enhancements>Graphics) N64 Mode", CVAR_LOW_RES_MODE, false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); - } + // N64 Mode toggle (again for convenience) + // UIWidgets::PaddedEnhancementCheckbox("(Enhancements>Graphics) N64 Mode", CVAR_LOW_RES_MODE, false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); + } - UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); - // Activator - UIWidgets::PaddedEnhancementCheckbox("Enable advanced settings.", CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", false, false, - false, "", UIWidgets::CheckboxGraphics::Cross, false); - // Error/Warning display - if (!CVarGetInteger(CVAR_LOW_RES_MODE, 0)) { - if (IsDroppingFrames()) { // Significant frame drop warning - ImGui::TextColored(messageColor[MESSAGE_WARNING], - ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring."); - UIWidgets::Spacer(2); - } else { // No warnings - UIWidgets::Spacer(enhancementSpacerHeight); - } - } else { // N64 Mode warning - ImGui::TextColored(messageColor[MESSAGE_QUESTION], - ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings."); - ImGui::SameLine(); - if (ImGui::Button("Click to disable")) { - CVarSetInteger(CVAR_LOW_RES_MODE, 0); - CVarSave(); - } - } - // Resolution visualiser - ImGui::Text("Viewport dimensions: %d x %d", gfx_current_game_window_viewport.width, - gfx_current_game_window_viewport.height); - ImGui::Text("Internal resolution: %d x %d", gfx_current_dimensions.width, gfx_current_dimensions.height); - - UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); - if (disabled_everything) { // Hide aspect ratio controls. - UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + // Activator + UIWidgets::PaddedEnhancementCheckbox("Enable advanced settings.", CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", false, false, + false, "", UIWidgets::CheckboxGraphics::Cross, false); + // Error/Warning display + if (!CVarGetInteger(CVAR_LOW_RES_MODE, 0)) { + if (IsDroppingFrames()) { // Significant frame drop warning + ImGui::TextColored(messageColor[MESSAGE_WARNING], + ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring."); + UIWidgets::Spacer(2); + } else { // No warnings + UIWidgets::Spacer(enhancementSpacerHeight); } - - // Aspect Ratio - ImGui::Text("Force aspect ratio:"); + } else { // N64 Mode warning + ImGui::TextColored(messageColor[MESSAGE_QUESTION], + ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings."); ImGui::SameLine(); - ImGui::TextColored(messageColor[MESSAGE_GRAY_75], "(Select \"Off\" to disable.)"); - // Presets - if (ImGui::Combo(" ", &item_aspectRatio, aspectRatioPresetLabels, - IM_ARRAYSIZE(aspectRatioPresetLabels)) && - item_aspectRatio != default_aspectRatio) { // don't change anything if "Custom" is selected. - aspectRatioX = aspectRatioPresetsX[item_aspectRatio]; - aspectRatioY = aspectRatioPresetsY[item_aspectRatio]; - - if (showHorizontalResField) { - horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - } - - CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX); - CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY); - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); + if (ImGui::Button("Click to disable")) { + CVarSetInteger(CVAR_LOW_RES_MODE, 0); CVarSave(); } - // Hide aspect ratio input fields if using one of the presets. - if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) { - // Declare input interaction bools outside of IF statement to prevent Y field from disappearing. - const bool input_X = ImGui::InputFloat("X", &aspectRatioX, 0.1f, 1.0f, "%.3f"); - const bool input_Y = ImGui::InputFloat("Y", &aspectRatioY, 0.1f, 1.0f, "%.3f"); - if (input_X || input_Y) { - item_aspectRatio = default_aspectRatio; - update[UPDATE_aspectRatioX] = true; - update[UPDATE_aspectRatioY] = true; - } - } else if (showHorizontalResField) { // Show calculated aspect ratio - if (item_aspectRatio) { - UIWidgets::Spacer(2); - const float resolvedAspectRatio = (float)gfx_current_dimensions.width / gfx_current_dimensions.height; - ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio); - } else { - UIWidgets::Spacer(enhancementSpacerHeight); - } - } + } + // Resolution visualiser + ImGui::Text("Viewport dimensions: %d x %d", gfx_current_game_window_viewport.width, + gfx_current_game_window_viewport.height); + ImGui::Text("Internal resolution: %d x %d", gfx_current_dimensions.width, gfx_current_dimensions.height); + + UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + if (disabled_everything) { // Hide aspect ratio controls. + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + + // Aspect Ratio + ImGui::Text("Force aspect ratio:"); + ImGui::SameLine(); + ImGui::TextColored(messageColor[MESSAGE_GRAY_75], "(Select \"Off\" to disable.)"); + // Presets + if (ImGui::Combo(" ", &item_aspectRatio, aspectRatioPresetLabels, + IM_ARRAYSIZE(aspectRatioPresetLabels)) && + item_aspectRatio != default_aspectRatio) { // don't change anything if "Custom" is selected. + aspectRatioX = aspectRatioPresetsX[item_aspectRatio]; + aspectRatioY = aspectRatioPresetsY[item_aspectRatio]; - if (disabled_everything) { // Hide aspect ratio controls. - UIWidgets::ReEnableComponent("disabledTooltipText"); + if (showHorizontalResField) { + horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; } - UIWidgets::Spacer(0); - // Vertical Resolution - UIWidgets::PaddedEnhancementCheckbox("Set fixed vertical resolution (disables Resolution slider)", - CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", true, false, - disabled_everything, "", UIWidgets::CheckboxGraphics::Cross, false); - UIWidgets::Tooltip( - "Override the resolution scale slider and use the settings below, irrespective of window size."); - if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls. - UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX); + CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY); + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); + CVarSave(); + } + // Hide aspect ratio input fields if using one of the presets. + if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) { + // Declare input interaction bools outside of IF statement to prevent Y field from disappearing. + const bool input_X = ImGui::InputFloat("X", &aspectRatioX, 0.1f, 1.0f, "%.3f"); + const bool input_Y = ImGui::InputFloat("Y", &aspectRatioY, 0.1f, 1.0f, "%.3f"); + if (input_X || input_Y) { + item_aspectRatio = default_aspectRatio; + update[UPDATE_aspectRatioX] = true; + update[UPDATE_aspectRatioY] = true; } - if (ImGui::Combo("Pixel Count Presets", &item_pixelCount, pixelCountPresetLabels, - IM_ARRAYSIZE(pixelCountPresetLabels)) && - item_pixelCount != default_pixelCount) { // don't change anything if "Custom" is selected. - verticalPixelCount = pixelCountPresets[item_pixelCount]; + } else if (showHorizontalResField) { // Show calculated aspect ratio + if (item_aspectRatio) { + UIWidgets::Spacer(2); + const float resolvedAspectRatio = (float)gfx_current_dimensions.width / gfx_current_dimensions.height; + ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio); + } else { + UIWidgets::Spacer(enhancementSpacerHeight); + } + } - if (showHorizontalResField) { - horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - } + if (disabled_everything) { // Hide aspect ratio controls. + UIWidgets::ReEnableComponent("disabledTooltipText"); + } + UIWidgets::Spacer(0); + + // Vertical Resolution + UIWidgets::PaddedEnhancementCheckbox("Set fixed vertical resolution (disables Resolution slider)", + CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", true, false, + disabled_everything, "", UIWidgets::CheckboxGraphics::Cross, false); + UIWidgets::Tooltip( + "Override the resolution scale slider and use the settings below, irrespective of window size."); + if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls. + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + if (ImGui::Combo("Pixel Count Presets", &item_pixelCount, pixelCountPresetLabels, + IM_ARRAYSIZE(pixelCountPresetLabels)) && + item_pixelCount != default_pixelCount) { // don't change anything if "Custom" is selected. + verticalPixelCount = pixelCountPresets[item_pixelCount]; - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount); - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); - CVarSave(); - } - // Horizontal Resolution, if visibility is enabled for it. if (showHorizontalResField) { - // Only show the field if Aspect Ratio is being enforced. - if ((aspectRatioX > 0.0f) && (aspectRatioY > 0.0f)) { - // So basically we're "faking" this one by setting aspectRatioX instead. - if (ImGui::InputInt("Horiz. Pixel Count", &horizontalPixelCount, 8, 320)) { - item_aspectRatio = default_aspectRatio; - if (horizontalPixelCount < SCREEN_WIDTH) { - horizontalPixelCount = SCREEN_WIDTH; - } - aspectRatioX = horizontalPixelCount; - aspectRatioY = verticalPixelCount; - update[UPDATE_aspectRatioX] = true; - update[UPDATE_aspectRatioY] = true; - } - } else { // Display a notice instead. - ImGui::TextColored(messageColor[MESSAGE_QUESTION], - ICON_FA_QUESTION_CIRCLE " \"Force aspect ratio\" required."); - // ImGui::Text(" "); - ImGui::SameLine(); - if (ImGui::Button("Click to resolve")) { - item_aspectRatio = default_aspectRatio; // Set it to Custom - aspectRatioX = aspectRatioPresetsX[2]; // but use the 4:3 defaults - aspectRatioY = aspectRatioPresetsY[2]; - update[UPDATE_aspectRatioX] = true; - update[UPDATE_aspectRatioY] = true; - horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - } - } + horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; } - // Vertical Resolution part 2 - if (ImGui::InputInt("Vertical Pixel Count", &verticalPixelCount, 8, 240)) { - item_pixelCount = default_pixelCount; - update[UPDATE_verticalPixelCount] = true; - - // Account for the natural instinct to enter horizontal first. - // Ignore vertical resolutions that are below the lower clamp constant. - if (showHorizontalResField && !(verticalPixelCount < minVerticalPixelCount)) { + + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount); + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); + CVarSave(); + } + // Horizontal Resolution, if visibility is enabled for it. + if (showHorizontalResField) { + // Only show the field if Aspect Ratio is being enforced. + if ((aspectRatioX > 0.0f) && (aspectRatioY > 0.0f)) { + // So basically we're "faking" this one by setting aspectRatioX instead. + if (ImGui::InputInt("Horiz. Pixel Count", &horizontalPixelCount, 8, 320)) { item_aspectRatio = default_aspectRatio; + if (horizontalPixelCount < SCREEN_WIDTH) { + horizontalPixelCount = SCREEN_WIDTH; + } aspectRatioX = horizontalPixelCount; aspectRatioY = verticalPixelCount; update[UPDATE_aspectRatioX] = true; update[UPDATE_aspectRatioY] = true; } + } else { // Display a notice instead. + ImGui::TextColored(messageColor[MESSAGE_QUESTION], + ICON_FA_QUESTION_CIRCLE " \"Force aspect ratio\" required."); + // ImGui::Text(" "); + ImGui::SameLine(); + if (ImGui::Button("Click to resolve")) { + item_aspectRatio = default_aspectRatio; // Set it to Custom + aspectRatioX = aspectRatioPresetsX[2]; // but use the 4:3 defaults + aspectRatioY = aspectRatioPresetsY[2]; + update[UPDATE_aspectRatioX] = true; + update[UPDATE_aspectRatioY] = true; + horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; + } } - if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls. - UIWidgets::ReEnableComponent("disabledTooltipText"); + } + // Vertical Resolution part 2 + if (ImGui::InputInt("Vertical Pixel Count", &verticalPixelCount, 8, 240)) { + item_pixelCount = default_pixelCount; + update[UPDATE_verticalPixelCount] = true; + + // Account for the natural instinct to enter horizontal first. + // Ignore vertical resolutions that are below the lower clamp constant. + if (showHorizontalResField && !(verticalPixelCount < minVerticalPixelCount)) { + item_aspectRatio = default_aspectRatio; + aspectRatioX = horizontalPixelCount; + aspectRatioY = verticalPixelCount; + update[UPDATE_aspectRatioX] = true; + update[UPDATE_aspectRatioY] = true; } + } + if (disabled_pixelCount || disabled_everything) { // Hide pixel count controls. + UIWidgets::ReEnableComponent("disabledTooltipText"); + } - UIWidgets::Spacer(0); - - // Integer scaling settings group (Pixel-perfect Mode) - static const ImGuiTreeNodeFlags IntegerScalingResolvedImGuiFlag = - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) ? ImGuiTreeNodeFlags_DefaultOpen - : ImGuiTreeNodeFlags_None; - if (ImGui::CollapsingHeader("Integer Scaling Settings", IntegerScalingResolvedImGuiFlag)) { - const bool disabled_pixelPerfectMode = - !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything; - // Pixel-perfect Mode - UIWidgets::PaddedEnhancementCheckbox("Pixel-perfect Mode", CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", true, - true, disabled_pixelCount || disabled_everything, "", - UIWidgets::CheckboxGraphics::Cross, false); - UIWidgets::Tooltip("Don't scale image to fill window."); - if (disabled_pixelCount && CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0)) { - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0); - CVarSave(); - } + UIWidgets::Spacer(0); + + // Integer scaling settings group (Pixel-perfect Mode) + static const ImGuiTreeNodeFlags IntegerScalingResolvedImGuiFlag = + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) ? ImGuiTreeNodeFlags_DefaultOpen + : ImGuiTreeNodeFlags_None; + if (ImGui::CollapsingHeader("Integer Scaling Settings", IntegerScalingResolvedImGuiFlag)) { + const bool disabled_pixelPerfectMode = + !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything; + // Pixel-perfect Mode + UIWidgets::PaddedEnhancementCheckbox("Pixel-perfect Mode", CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", true, + true, disabled_pixelCount || disabled_everything, "", + UIWidgets::CheckboxGraphics::Cross, false); + UIWidgets::Tooltip("Don't scale image to fill window."); + if (disabled_pixelCount && CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0)) { + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0); + CVarSave(); + } - // Integer Scaling - UIWidgets::EnhancementSliderInt( - "Integer scale factor: %d", "##ARSIntScale", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", 1, - max_integerScaleFactor, "%d", 1, true, - disabled_pixelPerfectMode || CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0)); - UIWidgets::Tooltip("Integer scales the image. Only available in pixel-perfect mode."); - // Display warning if size is being clamped or if framebuffer is larger than viewport. - if (!disabled_pixelPerfectMode && - (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) && - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", 1) > integerScale_maximumBounds)) { - ImGui::SameLine(); - ImGui::TextColored(messageColor[MESSAGE_WARNING], ICON_FA_EXCLAMATION_TRIANGLE " Window exceeded."); - } + // Integer Scaling + UIWidgets::EnhancementSliderInt( + "Integer scale factor: %d", "##ARSIntScale", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", 1, + max_integerScaleFactor, "%d", 1, true, + disabled_pixelPerfectMode || CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0)); + UIWidgets::Tooltip("Integer scales the image. Only available in pixel-perfect mode."); + // Display warning if size is being clamped or if framebuffer is larger than viewport. + if (!disabled_pixelPerfectMode && + (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) && + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", 1) > integerScale_maximumBounds)) { + ImGui::SameLine(); + ImGui::TextColored(messageColor[MESSAGE_WARNING], ICON_FA_EXCLAMATION_TRIANGLE " Window exceeded."); + } - UIWidgets::PaddedEnhancementCheckbox( - "Automatically scale image to fit viewport", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", true, - true, disabled_pixelPerfectMode, "", UIWidgets::CheckboxGraphics::Cross, false); - UIWidgets::Tooltip("Automatically sets scale factor to fit window. Only available in pixel-perfect mode."); - if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0)) { - // This is just here to update the value shown on the slider. - // The function in LUS to handle this setting will ignore IntegerScaleFactor while active. - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", integerScale_maximumBounds); - // CVarSave(); - } - } // End of integer scaling settings + UIWidgets::PaddedEnhancementCheckbox( + "Automatically scale image to fit viewport", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", true, + true, disabled_pixelPerfectMode, "", UIWidgets::CheckboxGraphics::Cross, false); + UIWidgets::Tooltip("Automatically sets scale factor to fit window. Only available in pixel-perfect mode."); + if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0)) { + // This is just here to update the value shown on the slider. + // The function in LUS to handle this setting will ignore IntegerScaleFactor while active. + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.Factor", integerScale_maximumBounds); + // CVarSave(); + } + } // End of integer scaling settings - UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); - // Collapsible panel for additional settings - if (ImGui::CollapsingHeader("Additional Settings")) { - UIWidgets::Spacer(0); + // Collapsible panel for additional settings + if (ImGui::CollapsingHeader("Additional Settings")) { + UIWidgets::Spacer(0); #if defined(__SWITCH__) || defined(__WIIU__) - // Disable aspect correction, stretching the framebuffer to fill the viewport. - // This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles. - // The associated cvar is still functional on PC platforms if you want to use it though. - UIWidgets::PaddedEnhancementCheckbox("Disable aspect correction and stretch the output image.\n" - "(Might be useful for 4:3 televisions!)\n" - "Not available in Pixel Perfect Mode.", - CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", false, true, - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || - disabled_everything, - "", UIWidgets::CheckboxGraphics::Cross, false); + // Disable aspect correction, stretching the framebuffer to fill the viewport. + // This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles. + // The associated cvar is still functional on PC platforms if you want to use it though. + UIWidgets::PaddedEnhancementCheckbox("Disable aspect correction and stretch the output image.\n" + "(Might be useful for 4:3 televisions!)\n" + "Not available in Pixel Perfect Mode.", + CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", false, true, + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || + disabled_everything, + "", UIWidgets::CheckboxGraphics::Cross, false); #else - if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0)) { - // This setting is intentionally not exposed on PC platforms, - // but may be accidentally activated for varying reasons. - // Having this button should hopefully prevent support headaches. - ImGui::TextColored(messageColor[MESSAGE_QUESTION], ICON_FA_QUESTION_CIRCLE - " If the image is stretched and you don't know why, click this."); - if (ImGui::Button("Click to reenable aspect correction.")) { - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0); - CVarSave(); - } - UIWidgets::Spacer(2); + if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0)) { + // This setting is intentionally not exposed on PC platforms, + // but may be accidentally activated for varying reasons. + // Having this button should hopefully prevent support headaches. + ImGui::TextColored(messageColor[MESSAGE_QUESTION], ICON_FA_QUESTION_CIRCLE + " If the image is stretched and you don't know why, click this."); + if (ImGui::Button("Click to reenable aspect correction.")) { + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0); + CVarSave(); } + UIWidgets::Spacer(2); + } #endif - // A requested addition; an alternative way of displaying the resolution field. - if (ImGui::Checkbox("Show a horizontal resolution field, instead of aspect ratio.", &showHorizontalResField)) { - if (!showHorizontalResField && (aspectRatioX > 0.0f)) { // when turning this setting off - // Refresh relevant values - aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount; + // A requested addition; an alternative way of displaying the resolution field. + if (ImGui::Checkbox("Show a horizontal resolution field, instead of aspect ratio.", &showHorizontalResField)) { + if (!showHorizontalResField && (aspectRatioX > 0.0f)) { // when turning this setting off + // Refresh relevant values + aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount; + horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; + } else { // when turning this setting on + item_aspectRatio = default_aspectRatio; + if (aspectRatioX > 0.0f) { + // Refresh relevant values in the opposite order horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - } else { // when turning this setting on - item_aspectRatio = default_aspectRatio; - if (aspectRatioX > 0.0f) { - // Refresh relevant values in the opposite order - horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX; - aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount; - } + aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount; } - update[UPDATE_aspectRatioX] = true; } + update[UPDATE_aspectRatioX] = true; + } - // Beginning of Integer Scaling additional settings. - { - // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + // Beginning of Integer Scaling additional settings. + { + // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); - // Integer Scaling - Never Exceed Bounds. - const bool disabled_neverExceedBounds = - !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0) || disabled_everything; - const bool checkbox_neverExceedBounds = - UIWidgets::PaddedEnhancementCheckbox("Prevent integer scaling from exceeding screen bounds.\n" - "(Makes screen bounds take priority over specified factor.)", - CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", - true, false, disabled_neverExceedBounds, "", - UIWidgets::CheckboxGraphics::Cross, true); - UIWidgets::Tooltip( - "Prevents integer scaling factor from exceeding screen bounds.\n\n" - "Enabled: Will clamp the scaling factor and display a gentle warning in the resolution editor.\n" - "Disabled: Will allow scaling to exceed screen bounds, for users who want to crop overscan.\n\n" - " " ICON_FA_INFO_CIRCLE - " Please note that exceeding screen bounds may show a scroll bar on-screen."); - - // Initialise the (currently unused) "Exceed Bounds By" cvar if it's been changed. - if (checkbox_neverExceedBounds && - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); - CVarSave(); - } + // Integer Scaling - Never Exceed Bounds. + const bool disabled_neverExceedBounds = + !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.FitAutomatically", 0) || disabled_everything; + const bool checkbox_neverExceedBounds = + UIWidgets::PaddedEnhancementCheckbox("Prevent integer scaling from exceeding screen bounds.\n" + "(Makes screen bounds take priority over specified factor.)", + CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", + true, false, disabled_neverExceedBounds, "", + UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip( + "Prevents integer scaling factor from exceeding screen bounds.\n\n" + "Enabled: Will clamp the scaling factor and display a gentle warning in the resolution editor.\n" + "Disabled: Will allow scaling to exceed screen bounds, for users who want to crop overscan.\n\n" + " " ICON_FA_INFO_CIRCLE + " Please note that exceeding screen bounds may show a scroll bar on-screen."); - // Integer Scaling - Exceed Bounds By 1x/Offset. - // A popular feature in some retro frontends/upscalers, sometimes called "crop overscan" or "1080p 5x". - /* - UIWidgets::PaddedEnhancementCheckbox("Allow integer scale factor to go +1 above maximum screen bounds.", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", false, false, !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything, "", UIWidgets::CheckboxGraphics::Cross, false); - */ - // It does actually function as expected, but exceeding the bottom of the screen shows a scroll bar. - // I've ended up commenting this one out because of the scroll bar, and for simplicity. - - // Display an info message about the scroll bar. - if (!CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) || - CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { - if (disabled_neverExceedBounds) { // Dim this help text accordingly - UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); - } - ImGui::TextColored(messageColor[MESSAGE_INFO], - " " ICON_FA_INFO_CIRCLE - " A scroll bar may become visible if screen bounds are exceeded."); - if (disabled_neverExceedBounds) { // Dim this help text accordingly - UIWidgets::ReEnableComponent("disabledTooltipText"); - } + // Initialise the (currently unused) "Exceed Bounds By" cvar if it's been changed. + if (checkbox_neverExceedBounds && + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); + CVarSave(); + } + + // Integer Scaling - Exceed Bounds By 1x/Offset. + // A popular feature in some retro frontends/upscalers, sometimes called "crop overscan" or "1080p 5x". + /* + UIWidgets::PaddedEnhancementCheckbox("Allow integer scale factor to go +1 above maximum screen bounds.", CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", false, false, !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".PixelPerfectMode", 0) || disabled_everything, "", UIWidgets::CheckboxGraphics::Cross, false); + */ + // It does actually function as expected, but exceeding the bottom of the screen shows a scroll bar. + // I've ended up commenting this one out because of the scroll bar, and for simplicity. + + // Display an info message about the scroll bar. + if (!CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.NeverExceedBounds", 1) || + CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { + if (disabled_neverExceedBounds) { // Dim this help text accordingly + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + ImGui::TextColored(messageColor[MESSAGE_INFO], + " " ICON_FA_INFO_CIRCLE + " A scroll bar may become visible if screen bounds are exceeded."); + if (disabled_neverExceedBounds) { // Dim this help text accordingly + UIWidgets::ReEnableComponent("disabledTooltipText"); + } - // Another support helper button, to disable the unused "Exceed Bounds By" cvar. - // (Remove this button if uncommenting the checkbox.) - if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { - if (ImGui::Button("Click to reset a console variable that may be causing this.")) { - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); - CVarSave(); - } + // Another support helper button, to disable the unused "Exceed Bounds By" cvar. + // (Remove this button if uncommenting the checkbox.) + if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0)) { + if (ImGui::Button("Click to reset a console variable that may be causing this.")) { + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IntegerScale.ExceedBoundsBy", 0); + CVarSave(); } - } else { - ImGui::Text(" "); } - // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); - } // End of Integer Scaling additional settings. + } else { + ImGui::Text(" "); + } + // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + } // End of Integer Scaling additional settings. - } // End of additional settings + } // End of additional settings - // Clamp and update the cvars that don't use UIWidgets - if (update[UPDATE_aspectRatioX] || update[UPDATE_aspectRatioY] || update[UPDATE_verticalPixelCount]) { - if (update[UPDATE_aspectRatioX]) { - if (aspectRatioX < 0.0f) { - aspectRatioX = 0.0f; - } - CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX); + // Clamp and update the cvars that don't use UIWidgets + if (update[UPDATE_aspectRatioX] || update[UPDATE_aspectRatioY] || update[UPDATE_verticalPixelCount]) { + if (update[UPDATE_aspectRatioX]) { + if (aspectRatioX < 0.0f) { + aspectRatioX = 0.0f; } - if (update[UPDATE_aspectRatioY]) { - if (aspectRatioY < 0.0f) { - aspectRatioY = 0.0f; - } - CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY); + CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioX", aspectRatioX); + } + if (update[UPDATE_aspectRatioY]) { + if (aspectRatioY < 0.0f) { + aspectRatioY = 0.0f; } - if (update[UPDATE_verticalPixelCount]) { - // There's a upper and lower clamp on the Libultraship side too, - // so clamping it here is entirely visual, so the vertical resolution field reflects it. - if (verticalPixelCount < minVerticalPixelCount) { - verticalPixelCount = minVerticalPixelCount; - } - if (verticalPixelCount > maxVerticalPixelCount) { - verticalPixelCount = maxVerticalPixelCount; - } - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount); + CVarSetFloat(CVAR_PREFIX_ADVANCED_RESOLUTION ".AspectRatioY", aspectRatioY); + } + if (update[UPDATE_verticalPixelCount]) { + // There's a upper and lower clamp on the Libultraship side too, + // so clamping it here is entirely visual, so the vertical resolution field reflects it. + if (verticalPixelCount < minVerticalPixelCount) { + verticalPixelCount = minVerticalPixelCount; } - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); - CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); - CVarSave(); + if (verticalPixelCount > maxVerticalPixelCount) { + verticalPixelCount = maxVerticalPixelCount; + } + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", verticalPixelCount); } + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.AspectRatio", item_aspectRatio); + CVarSetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".UIComboItem.PixelCount", item_pixelCount); + CVarSave(); } - ImGui::End(); } void AdvancedResolutionSettingsWindow::UpdateElement() { diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index 71a3660217f..df475447d44 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -164,41 +164,41 @@ namespace SohGui { SPDLOG_ERROR("Could not find input editor window"); } - mAudioEditorWindow = std::make_shared(CVAR_WINDOW("AudioEditor"), "Audio Editor"); + mAudioEditorWindow = std::make_shared(CVAR_WINDOW("AudioEditor"), "Audio Editor", ImVec2(820, 630)); gui->AddGuiWindow(mAudioEditorWindow); mInputViewer = std::make_shared(CVAR_WINDOW("InputViewer"), "Input Viewer"); gui->AddGuiWindow(mInputViewer); - mInputViewerSettings = std::make_shared(CVAR_WINDOW("InputViewerSettings"), "Input Viewer Settings"); + mInputViewerSettings = std::make_shared(CVAR_WINDOW("InputViewerSettings"), "Input Viewer Settings", ImVec2(500, 525)); gui->AddGuiWindow(mInputViewerSettings); - mCosmeticsEditorWindow = std::make_shared(CVAR_WINDOW("CosmeticsEditor"), "Cosmetics Editor"); + mCosmeticsEditorWindow = std::make_shared(CVAR_WINDOW("CosmeticsEditor"), "Cosmetics Editor", ImVec2(550, 520)); gui->AddGuiWindow(mCosmeticsEditorWindow); - mActorViewerWindow = std::make_shared(CVAR_WINDOW("ActorViewer"), "Actor Viewer"); + mActorViewerWindow = std::make_shared(CVAR_WINDOW("ActorViewer"), "Actor Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mActorViewerWindow); - mColViewerWindow = std::make_shared(CVAR_WINDOW("CollisionViewer"), "Collision Viewer"); + mColViewerWindow = std::make_shared(CVAR_WINDOW("CollisionViewer"), "Collision Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mColViewerWindow); - mSaveEditorWindow = std::make_shared(CVAR_WINDOW("SaveEditor"), "Save Editor"); + mSaveEditorWindow = std::make_shared(CVAR_WINDOW("SaveEditor"), "Save Editor", ImVec2(520, 600)); gui->AddGuiWindow(mSaveEditorWindow); - mDLViewerWindow = std::make_shared(CVAR_WINDOW("DLViewer"), "Display List Viewer"); + mDLViewerWindow = std::make_shared(CVAR_WINDOW("DLViewer"), "Display List Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mDLViewerWindow); - mValueViewerWindow = std::make_shared(CVAR_WINDOW("ValueViewer"), "Value Viewer"); + mValueViewerWindow = std::make_shared(CVAR_WINDOW("ValueViewer"), "Value Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mValueViewerWindow); - mMessageViewerWindow = std::make_shared(CVAR_WINDOW("MessageViewer"), "Message Viewer"); + mMessageViewerWindow = std::make_shared(CVAR_WINDOW("MessageViewer"), "Message Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mMessageViewerWindow); - mGameplayStatsWindow = std::make_shared(CVAR_WINDOW("GameplayStats"), "Gameplay Stats"); + mGameplayStatsWindow = std::make_shared(CVAR_WINDOW("GameplayStats"), "Gameplay Stats", ImVec2(480, 550)); gui->AddGuiWindow(mGameplayStatsWindow); mCheckTrackerWindow = std::make_shared(CVAR_WINDOW("CheckTracker"), "Check Tracker"); gui->AddGuiWindow(mCheckTrackerWindow); - mCheckTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("CheckTrackerSettings"), "Check Tracker Settings"); + mCheckTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("CheckTrackerSettings"), "Check Tracker Settings", ImVec2(600, 375)); gui->AddGuiWindow(mCheckTrackerSettingsWindow); mEntranceTrackerWindow = std::make_shared(CVAR_WINDOW("EntranceTracker"),"Entrance Tracker"); gui->AddGuiWindow(mEntranceTrackerWindow); mItemTrackerWindow = std::make_shared(CVAR_WINDOW("ItemTracker"), "Item Tracker"); gui->AddGuiWindow(mItemTrackerWindow); - mItemTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("ItemTrackerSettings"), "Item Tracker Settings"); + mItemTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("ItemTrackerSettings"), "Item Tracker Settings", ImVec2(733, 472)); gui->AddGuiWindow(mItemTrackerSettingsWindow); - mRandomizerSettingsWindow = std::make_shared(CVAR_WINDOW("RandomizerSettings"), "Randomizer Settings"); + mRandomizerSettingsWindow = std::make_shared(CVAR_WINDOW("RandomizerSettings"), "Randomizer Settings", ImVec2(920, 600)); gui->AddGuiWindow(mRandomizerSettingsWindow); - mAdvancedResolutionSettingsWindow = std::make_shared(CVAR_WINDOW("AdvancedResolutionEditor"), "Advanced Resolution Settings"); + mAdvancedResolutionSettingsWindow = std::make_shared(CVAR_WINDOW("AdvancedResolutionEditor"), "Advanced Resolution Settings", ImVec2(497, 599)); gui->AddGuiWindow(mAdvancedResolutionSettingsWindow); mModalWindow = std::make_shared(CVAR_WINDOW("ModalWindow"), "Modal Window"); gui->AddGuiWindow(mModalWindow); diff --git a/soh/soh/SohModals.cpp b/soh/soh/SohModals.cpp index 44dc93d743e..b77a5f47fc9 100644 --- a/soh/soh/SohModals.cpp +++ b/soh/soh/SohModals.cpp @@ -19,6 +19,15 @@ struct SohModal { }; std::vector modals; +void SohModalWindow::Draw() { + if (!IsVisible()) { + return; + } + DrawElement(); + // Sync up the IsVisible flag if it was changed by ImGui + SyncVisibilityConsoleVariable(); +} + void SohModalWindow::DrawElement() { if (modals.size() > 0) { SohModal curModal = modals.at(0); diff --git a/soh/soh/SohModals.h b/soh/soh/SohModals.h index b64e180b688..f584b954019 100644 --- a/soh/soh/SohModals.h +++ b/soh/soh/SohModals.h @@ -7,6 +7,7 @@ class SohModalWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; + void Draw() override; void InitElement() override {}; void DrawElement() override; From c507d4d9a04c57a72d4816cdbe71c76e8aa9b110 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Fri, 13 Sep 2024 00:01:57 +0100 Subject: [PATCH 05/43] Early Eyeball Frog (#4120) * early eyeball is real :D * make cvar * update cvars * fix additional cvar check bug --- soh/soh/SohMenuBar.cpp | 2 + soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 113 +++++++++++++++----- 2 files changed, 86 insertions(+), 29 deletions(-) diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 5568841b610..05f22fb2d7e 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1421,6 +1421,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Restore a bug from NTSC 1.0 that allows bypassing Bongo Bongo's intro cutscene to quickly kill him"); UIWidgets::PaddedEnhancementCheckbox("Original RBA Values", CVAR_ENHANCEMENT("RestoreRBAValues"), true, false); UIWidgets::Tooltip("Restores the original outcomes when performing Reverse Bottle Adventure."); + UIWidgets::PaddedEnhancementCheckbox("Early Eyeball Frog", CVAR_ENHANCEMENT("EarlyEyeballFrog"), true, false); + UIWidgets::Tooltip("Restores a bug from NTSC 1.0/1.1 that allows you to obtain the eyeball frog from King Zora instead of the Zora Tunic by holding shield."); ImGui::EndMenu(); } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 73157aedf52..7b6afefaaa1 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -128,18 +128,41 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_DONE: - ret = NPC_TALK_STATE_IDLE; - switch (this->actor.textId) { - case 0x4012: - Flags_SetInfTable(INFTABLE_139); - ret = NPC_TALK_STATE_ACTION; - break; - case 0x401B: - ret = !Message_ShouldAdvance(play) ? NPC_TALK_STATE_TALKING : NPC_TALK_STATE_ACTION; - break; - case 0x401F: - Flags_SetInfTable(INFTABLE_139); - break; + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + if (Message_ShouldAdvance(play)) { + ret = NPC_TALK_STATE_ITEM_GIVEN; + } + } else { + ret = NPC_TALK_STATE_IDLE; + switch (this->actor.textId) { + case 0x4012: + Flags_SetInfTable(INFTABLE_139); + ret = NPC_TALK_STATE_ACTION; + break; + case 0x401B: + ret = !Message_ShouldAdvance(play) ? NPC_TALK_STATE_TALKING : NPC_TALK_STATE_ACTION; + break; + case 0x401F: + Flags_SetInfTable(INFTABLE_139); + break; + } + } + break; + case TEXT_STATE_CLOSING: + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + ret = NPC_TALK_STATE_IDLE; + switch (this->actor.textId) { + case 0x4012: + Flags_SetInfTable(INFTABLE_139); + ret = NPC_TALK_STATE_ACTION; + break; + case 0x401B: + ret = !Message_ShouldAdvance(play) ? NPC_TALK_STATE_TALKING : NPC_TALK_STATE_ACTION; + break; + case 0x401F: + Flags_SetInfTable(INFTABLE_139); + break; + } } break; case TEXT_STATE_DONE_FADING: @@ -160,7 +183,9 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { } if (this->actor.textId == 0x4014) { if (play->msgCtx.choiceIndex == 0) { - EnKz_SetupGetItem(this, play); + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + EnKz_SetupGetItem(this, play); + } ret = NPC_TALK_STATE_ACTION; } else { this->actor.textId = 0x4016; @@ -175,7 +200,6 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { break; case TEXT_STATE_NONE: case TEXT_STATE_DONE_HAS_NEXT: - case TEXT_STATE_CLOSING: case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: @@ -207,25 +231,34 @@ s32 func_80A9C95C(PlayState* play, EnKz* this, s16* talkState, f32 unkf, NpcGetT return 1; } - if (*talkState != NPC_TALK_STATE_IDLE) { - *talkState = updateTalkState(play, &this->actor); - return 0; - } + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, &this->actor); + return 0; + } - yaw = Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos); - yaw -= this->actor.shape.rot.y; - if ((fabsf(yaw) > 1638.0f) || (this->actor.xzDistToPlayer < 265.0f)) { - this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; - return 0; - } + yaw = Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos); + yaw -= this->actor.shape.rot.y; + if ((fabsf(yaw) > 1638.0f) || (this->actor.xzDistToPlayer < 265.0f)) { + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + return 0; + } - this->actor.flags |= ACTOR_FLAG_TARGETABLE; + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + } Actor_GetScreenPos(play, &this->actor, &sp32, &sp30); if (!((sp32 >= -30) && (sp32 < 361) && (sp30 >= -10) && (sp30 < 241))) { return 0; } + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, &this->actor); + return 0; + } + } + xzDistToPlayer = this->actor.xzDistToPlayer; this->actor.xzDistToPlayer = Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos); if (func_8002F2CC(&this->actor, play, unkf) == 0) { @@ -241,6 +274,18 @@ s32 func_80A9C95C(PlayState* play, EnKz* this, s16* talkState, f32 unkf, NpcGetT void func_80A9CB18(EnKz* this, PlayState* play) { Player* player = GET_PLAYER(play); + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + f32 yaw; + yaw = Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos); + yaw -= this->actor.shape.rot.y; + if ((fabsf(yaw) > 1638.0f) || (this->actor.xzDistToPlayer < 265.0f)) { + this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; + return 0; + } + + this->actor.flags |= ACTOR_FLAG_TARGETABLE; + } + if (func_80A9C95C(play, this, &this->interactInfo.talkState, 340.0f, EnKz_GetText, func_80A9C6C0)) { if (GameInteractor_Should(VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER, (this->actor.textId == 0x401A), this) && !Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) @@ -262,12 +307,15 @@ void func_80A9CB18(EnKz* this, PlayState* play) { this->actor.textId = 0x4014; this->sfxPlayed = false; player->actor.textId = this->actor.textId; - this->isTrading = true; + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + this->isTrading = true; + } return; } } - - this->isTrading = false; + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + this->isTrading = false; + } if (Flags_GetInfTable(INFTABLE_139)) { this->actor.textId = CHECK_QUEST_ITEM(QUEST_SONG_SERENADE) ? 0x4045 : 0x401A; player->actor.textId = this->actor.textId; @@ -434,6 +482,9 @@ void EnKz_StopMweep(EnKz* this, PlayState* play) { void EnKz_Wait(EnKz* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; + } this->actionFunc = EnKz_SetupGetItem; EnKz_SetupGetItem(this, play); } else { @@ -460,7 +511,11 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); } } else { - getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + getItemId = func_8002F368(play) == EXCH_ITEM_PRESCRIPTION ? GI_FROG : GI_TUNIC_ZORA; + } else { + getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; + } yRange = fabsf(this->actor.yDistToPlayer) + 1.0f; xzRange = this->actor.xzDistToPlayer + 1.0f; Actor_OfferGetItem(&this->actor, play, getItemId, xzRange, yRange); From 7f503c33d22738c8781e5efbb8170ea4d6b2d83e Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 14 Sep 2024 19:38:22 -0700 Subject: [PATCH 06/43] Concurrency Fix (#4318) * Removed all CVarLoad uses from code to prevent thread concurrency issues. * Add mutext locks to save and load functions to prevent concurrent operations between those two. --- soh/soh/Enhancements/debugconsole.cpp | 3 +-- soh/soh/Enhancements/randomizer/3drando/rando_main.cpp | 3 +-- soh/soh/Enhancements/randomizer/randomizer.cpp | 3 +-- soh/soh/SaveManager.cpp | 5 +++++ soh/soh/SaveManager.h | 1 + 5 files changed, 9 insertions(+), 6 deletions(-) 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/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 6f342535b00..9705d9a1430 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -22,8 +22,7 @@ void RandoMain::GenerateRando(std::unordered_map cvarS std::string fileName = Ship::Context::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, enabledTricks, seedString).c_str()); CVarSetString(CVAR_GENERAL("SpoilerLog"), fileName.c_str()); - CVarSave(); - CVarLoad(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); CVarSetInteger(CVAR_GENERAL("NewSeedGenerated"), 1); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 487348c9db7..d2a6c5029bf 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3053,8 +3053,7 @@ void GenerateRandomizerImgui(std::string seed = "") { RandoMain::GenerateRando(cvarSettings, excludedLocations, enabledTricks, seed); CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 0); - CVarSave(); - CVarLoad(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); generated = 1; } diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index b6fd0cb07c2..a1ea20b8a30 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -17,6 +17,7 @@ #include #include #include +#include extern "C" SaveContext gSaveContext; using namespace std::string_literals; @@ -909,6 +910,7 @@ int copy_file(const char* src, const char* dst) { // Threaded SaveFile takes copy of gSaveContext for local unmodified storage void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int sectionID) { + saveMtx.lock(); SPDLOG_INFO("Save File - fileNum: {}", fileNum); // Needed for first time save, hasn't changed in forever anyway saveBlock["version"] = 1; @@ -983,6 +985,7 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se InitMeta(fileNum); GameInteractor::Instance->ExecuteHooks(fileNum); SPDLOG_INFO("Save File Finish - fileNum: {}", fileNum); + saveMtx.unlock(); } // SaveSection creates a copy of gSaveContext to prevent mid-save data modification, and passes its reference to SaveFileThreaded @@ -1025,6 +1028,7 @@ void SaveManager::SaveGlobal() { } void SaveManager::LoadFile(int fileNum) { + saveMtx.lock(); SPDLOG_INFO("Load File - fileNum: {}", fileNum); std::filesystem::path fileName = GetFileName(fileNum); assert(std::filesystem::exists(fileName)); @@ -1087,6 +1091,7 @@ void SaveManager::LoadFile(int fileNum) { SohGui::RegisterPopup("Error loading save file", "A problem occurred loading the save in slot " + std::to_string(fileNum + 1) + ".\nSave file corruption is suspected.\n" + "The file has been renamed to prevent further issues."); } + saveMtx.unlock(); } void SaveManager::ThreadPoolWait() { diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 817fc6fbfb2..df54992778d 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -184,6 +184,7 @@ class SaveManager { nlohmann::json* currentJsonContext = nullptr; nlohmann::json::iterator currentJsonArrayContext; std::shared_ptr smThreadPool; + std::mutex saveMtx; }; #else From 19dc4dc0faa4a04b2d986e17b3e6dd2a79059baf Mon Sep 17 00:00:00 2001 From: Archez Date: Sat, 14 Sep 2024 23:13:46 -0400 Subject: [PATCH 07/43] Bump LUS (#4341) --- libultraship | 2 +- soh/soh/OTRGlobals.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libultraship b/libultraship index 92bce011545..0302eab051a 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 92bce01154589080e534c3c143913a196e161f02 +Subproject commit 0302eab051a7e0e5a8dc208aca5b00899a91808c diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 6e41eb7a8a8..6ab2f658aa7 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -338,7 +338,7 @@ OTRGlobals::OTRGlobals() { overlay->LoadFont("Fipps", "fonts/Fipps-Regular.otf", 32.0f); overlay->SetCurrentFont(CVarGetString(CVAR_GAME_OVERLAY_FONT, "Press Start 2P")); - context->InitAudio(); + context->InitAudio({ .SampleRate = 44100, .SampleLength = 1024, .DesiredBuffered = 2480 }); SPDLOG_INFO("Starting Ship of Harkinian version {} (Branch: {} | Commit: {})", (char*)gBuildVersion, (char*)gGitBranch, (char*)gGitCommitHash); From 8359d2a8f075e9c7efdf387b2f9e7d54f3e513e7 Mon Sep 17 00:00:00 2001 From: Archez Date: Sat, 14 Sep 2024 23:45:10 -0400 Subject: [PATCH 08/43] Update entrance tracker settings window for modern menu changes --- .../randomizer/randomizer_entrance_tracker.cpp | 9 --------- soh/soh/SohGui.cpp | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 09602e91754..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,6 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::EndTable(); } - - ImGui::End(); } void EntranceTrackerWindow::Draw() { diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index 13b58f48ff4..4bef8cea675 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -193,7 +193,7 @@ namespace SohGui { gui->AddGuiWindow(mCheckTrackerSettingsWindow); mEntranceTrackerWindow = std::make_shared(CVAR_WINDOW("EntranceTracker"), "Entrance Tracker"); gui->AddGuiWindow(mEntranceTrackerWindow); - mEntranceTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("EntranceTrackerSettings"), "Entrance Tracker Settings"); + mEntranceTrackerSettingsWindow = std::make_shared(CVAR_WINDOW("EntranceTrackerSettings"), "Entrance Tracker Settings", ImVec2(600, 375)); gui->AddGuiWindow(mEntranceTrackerSettingsWindow); mItemTrackerWindow = std::make_shared(CVAR_WINDOW("ItemTracker"), "Item Tracker"); gui->AddGuiWindow(mItemTrackerWindow); From c3602fde80dc277bcdeeca2d2c2a0d50fd57a7ed Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:36:06 +0100 Subject: [PATCH 09/43] rewrite MQ DC Logic --- soh/soh/Enhancements/debugconsole.cpp | 3 +- .../randomizer/3drando/location_access.cpp | 4 +- .../randomizer/3drando/location_access.hpp | 5 +- .../location_access/locacc_castle_town.cpp | 6 +- .../location_access/locacc_death_mountain.cpp | 6 +- .../locacc_dodongos_cavern.cpp | 221 +++++++++++++----- .../location_access/locacc_gerudo_valley.cpp | 2 +- .../location_access/locacc_hyrule_field.cpp | 2 +- .../location_access/locacc_kakariko.cpp | 2 +- .../location_access/locacc_lost_woods.cpp | 10 +- .../location_access/locacc_zoras_domain.cpp | 6 +- .../randomizer/3drando/rando_main.cpp | 3 +- soh/soh/Enhancements/randomizer/logic.cpp | 133 +++++++++-- soh/soh/Enhancements/randomizer/logic.h | 18 +- .../Enhancements/randomizer/randomizer.cpp | 3 +- .../Enhancements/randomizer/randomizerTypes.h | 35 ++- soh/soh/SaveManager.cpp | 5 + soh/soh/SaveManager.h | 1 + 18 files changed, 349 insertions(+), 116 deletions(-) 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/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 29b3cb2177c..820e3bea384 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -212,7 +212,7 @@ void Area::ResetVariables() { std::array areaTable; bool Here(const RandomizerRegion area, ConditionFn condition) { - return areaTable[area].HereCheck(condition); + return areaTable[area].Here(condition); } bool CanPlantBean(const RandomizerRegion area) { @@ -243,7 +243,7 @@ void AreaTable_Init() { randoCtx = Context::GetInstance().get(); logic = randoCtx->GetLogic(); grottoEvents = { - EventAccess(&logic->GossipStoneFairy, { [] { return logic->GossipStoneFairy || logic->CanSummonGossipFairy; } }), + EventAccess(&logic->GossipStoneFairy, { [] { return logic->CanSummonGossipFairy(); } }), EventAccess(&logic->ButterflyFairy, { [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); } }), EventAccess(&logic->BugShrub, { [] { return logic->CanCutShrubs; } }), EventAccess(&logic->LoneFish, { [] { return true; } }), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index 286551cab11..b9ecd5dc916 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -211,7 +211,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; @@ -249,12 +249,13 @@ class Area { extern std::array areaTable; extern std::vector grottoEvents; -bool Here(const RandomizerRegion area, ConditionFn condition); +bool Here(const RandomizerRegion area, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this 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 HereAsSameAge(const RandomizerRegion area, ConditionFn condition); //RANDOTODO make a less stupid way to check other at same age than self referncing with this #define DAY_NIGHT_CYCLE true #define NO_DAY_NIGHT_CYCLE false 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..59da13e339d 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 @@ -35,7 +35,7 @@ void AreaTable_Init_CastleTown() { areaTable[RR_TOT_ENTRANCE] = Area("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->CanSummonGossipFairyWithoutSuns();}}), }, { //Locations LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true), @@ -82,7 +82,7 @@ void AreaTable_Init_CastleTown() { areaTable[RR_HYRULE_CASTLE_GROUNDS] = Area("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->CanSummonGossipFairy();}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), EventAccess(&logic->BugRock, {[]{return true;}}), }, { @@ -121,7 +121,7 @@ void AreaTable_Init_CastleTown() { areaTable[RR_HC_STORMS_GROTTO] = Area("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->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CanSummonGossipFairy();}}), EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->CanBlastOrSmash;}}), }, { //Locations 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..1bf1963881f 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 @@ -27,7 +27,7 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Area("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->GossipStoneFairy, {[]{return logic->CanSummonGossipFairy();}}), EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations @@ -82,7 +82,7 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_GORON_CITY] = Area("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->CanSummonGossipFairyWithoutSuns();}}), EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), EventAccess(&logic->BugRock, {[]{return logic->BugRock || (logic->CanBlastOrSmash || logic->CanUse(RG_SILVER_GAUNTLETS));}}), EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}}), @@ -173,7 +173,7 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_DMC_UPPER_LOCAL] = Area("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->CanSummonGossipFairyWithoutSuns() && (logic->FireTimer >= 16 || logic->Hearts >= 3));}}), }, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer >= 16 || logic->Hearts >= 3), 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..d9178f333f8 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 @@ -22,22 +22,22 @@ void AreaTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BEGINNING] = Area("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->CanUse(RG_GORONS_BRACELET);});}}), }); areaTable[RR_DODONGOS_CAVERN_LOBBY] = Area("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->CanUse(RG_GORONS_BRACELET)) && logic->CanSummonGossipFairy();}}), }, { //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->CanUse(RG_GORONS_BRACELET);})), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku || logic->CanUse(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->CanUse(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->CanBlastOrSmash || logic->CanUse(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;});}}), @@ -86,7 +86,7 @@ void AreaTable_Init_DodongosCavern() { //Exits 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->CanBlastOrSmash || logic->CanUse(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, {}, { @@ -100,8 +100,8 @@ void AreaTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_STAIRS_LOWER] = Area("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->CanUse(RG_GORONS_BRACELET) || 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->CanUse(RG_GORONS_BRACELET);});}}), }); areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Area("Dodongos Cavern Stairs Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { @@ -119,7 +119,7 @@ void AreaTable_Init_DodongosCavern() { 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->CanUse(RG_GORONS_BRACELET);}}), }); areaTable[RR_DODONGOS_CAVERN_ARMOS_ROOM] = Area("Dodongos Cavern Armos Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -133,8 +133,8 @@ void AreaTable_Init_DodongosCavern() { 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_2F_SIDE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBlastOrSmash || (randoCtx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->CanUse(RG_GORONS_BRACELET));});}}), + Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBlastOrSmash || logic->CanUse(RG_GORONS_BRACELET);});}}), 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));}}), }); @@ -213,131 +213,224 @@ void AreaTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_BEGINNING] = Area("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->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET);});}}), }); areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Area("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->CanSummonGossipFairy();}}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBlastOrSmash || logic->GoronBracelet), + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBlastOrSmash || 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->CanBlastOrSmash || logic->GoronBracelet;})), + 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->CanBlastOrSmash;});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBlastOrSmash || 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->GoronBracelet && logic->CanTakeDamage;});}}), //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->GoronBracelet && + ((logic->IsAdult && randoCtx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || + (logic->IsChild && randoCtx->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] = Area("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->CanBlastOrSmash || 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) || (randoCtx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && logic->CanJumpslash && logic->CanTakeDamage);}}), //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] = Area("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) || (randoCtx->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) || + (randoCtx->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] = Area("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] = Area("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] = Area("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->CanTakeDamage;}}), + //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] = Area("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->CanUse(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->CanUse(RG_GORONS_BRACELET);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Area("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*/) && randoCtx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}}), + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->CanTakeDamage;}}), + 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*/) && randoCtx->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] = Area("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, {}, { //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] = Area("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->CanBlastOrSmash), //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] = Area("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->CanBlastOrSmash || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}));}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Area("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, {}, { //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->CanUse(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->CanUse(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, {}, { - //Locations - }, { + areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Area("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_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_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] = Area("Dodongos Cavern MQ Poes 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_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->CanUse(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_LOWER_RIGHT_SIDE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->CanUse(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->CanUse(RG_GORONS_BRACELET);});}}), }); - 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_MAD_SCRUB_ROOM] = Area("Dodongos Cavern Mad Scrub Room", "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_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_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_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_BEFORE_BOSS] = Area("Dodongos Cavern MQ Before Boss", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Area("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_BACK_BEHIND_FIRE] = Area("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), //pulling the grave isn't required, as you can open the chest through it + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return logic->CanAttack();}}), + //There's a trick N64 rolls into the child eyes trick for using armos blow up the bomb flowers when dieing, which would be killing an armos + Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, {[]{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_BACK_SWITCH_GRAVE] = Area("Dodongos Cavern MQ Back Switch Grave", "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->CanUse(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 }); + } /*--------------------------- @@ -361,7 +454,7 @@ void AreaTable_Init_DodongosCavern() { 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*/ + (logic->Bombs || logic->CanUse(RG_GORONS_BRACELET)) && logic->CanJumpslash)); /*todo add chu kill to tricks*/ }}), }, { 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..96a88f99c3d 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 @@ -21,7 +21,7 @@ void AreaTable_Init_GerudoValley() { areaTable[RR_GV_UPPER_STREAM] = Area("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->CanSummonGossipFairy();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations 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..436b1eb0f61 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 @@ -111,7 +111,7 @@ void AreaTable_Init_HyruleField() { areaTable[RR_LAKE_HYLIA] = Area("Lake Hylia", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanSummonGossipFairy();}}), 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);}}), 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..00f2d728a2a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -278,7 +278,7 @@ void AreaTable_Init_Kakariko() { areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Area("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->CanSummonGossipFairyWithoutSuns();}}), }, { //Locations LOCATION(RC_GRAVEYARD_GOSSIP_STONE, 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..c22867c59d6 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 @@ -7,7 +7,7 @@ void AreaTable_Init_LostWoods() { areaTable[RR_KOKIRI_FOREST] = Area("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->GossipStoneFairy, {[]{return logic->CanSummonGossipFairyWithoutSuns();}}), EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->KokiriSword && logic->DekuShield);}}), }, { //Locations @@ -24,7 +24,7 @@ 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)) || randoCtx->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;}}), @@ -42,7 +42,7 @@ void AreaTable_Init_LostWoods() { }, { //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_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || randoCtx->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, {}, { @@ -115,7 +115,7 @@ void AreaTable_Init_LostWoods() { //Events EventAccess(&logic->OddMushroomAccess, {[]{return logic->OddMushroomAccess || (logic->IsAdult && (logic->CojiroAccess || logic->Cojiro));}}), EventAccess(&logic->PoachersSawAccess, {[]{return logic->PoachersSawAccess || (logic->IsAdult && logic->OddPoulticeAccess);}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanSummonGossipFairyWithoutSuns();}}), EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs;}}), }, { @@ -204,7 +204,7 @@ void AreaTable_Init_LostWoods() { areaTable[RR_SACRED_FOREST_MEADOW] = Area("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->CanSummonGossipFairyWithoutSuns();}}), }, { //Locations LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->ZeldasLetter), 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..df0ab7e3ff9 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 @@ -15,7 +15,7 @@ void AreaTable_Init_ZorasDomain() { areaTable[RR_ZORAS_RIVER] = Area("Zora River", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanSummonGossipFairy();}}), 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;}}), @@ -85,7 +85,7 @@ void AreaTable_Init_ZorasDomain() { areaTable[RR_ZORAS_DOMAIN] = Area("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->GossipStoneFairy, {[]{return logic->CanSummonGossipFairyWithoutSuns();}}), EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), EventAccess(&logic->FishGroup, {[]{return logic->FishGroup || logic->IsChild;}}), @@ -149,7 +149,7 @@ void AreaTable_Init_ZorasDomain() { areaTable[RR_ZORAS_FOUNTAIN] = Area("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->CanSummonGossipFairyWithoutSuns();}}), EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), }, { //Locations diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 509c6f8528c..32d707b9596 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/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index edb17df0c88..1e0982d12f5 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -232,7 +232,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 && (BuyArrow || AmmoCanDrop);// || BowAsChild; case RG_MEGATON_HAMMER: return IsAdult;// || HammerAsChild; case RG_IRON_BOOTS: @@ -415,24 +415,125 @@ namespace Rando { 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 CanBlastOrSmash; + } + + bool Logic::CanSummonGossipFairyWithoutSuns() { + return GossipStoneFairy || CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); + } + + bool Logic::CanSummonGossipFairy() { + return CanSummonGossipFairyWithoutSuns() || CanUse(RG_SUNS_SONG); + } + + bool Logic::CanGetDekuBabaSticks() { + return DekuBabaSticks || (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG)); + } + + bool Logic::CanDamage() { + return Slingshot || CanJumpslash || HasExplosives || CanUse(RG_DINS_FIRE) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_FAIRY_BOW); + } + + bool Logic::CanAttack() { + return CanDamage() || CanUse(RG_BOOMERANG) || Hookshot; + } + + 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() { @@ -503,7 +604,7 @@ namespace Rando { BuyBombchus = (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant); Hookshot = CanUse(RG_HOOKSHOT); Longshot = CanUse(RG_LONGSHOT); - Bow = CanUse(RG_FAIRY_BOW) && (BuyArrow || AmmoCanDrop); + Bow = CanUse(RG_FAIRY_BOW); GoronBracelet = HasItem(RG_GORONS_BRACELET); SilverGauntlets = HasItem(RG_SILVER_GAUNTLETS); GoldenGauntlets = HasItem(RG_GOLDEN_GAUNTLETS); @@ -581,6 +682,7 @@ namespace Rando { // IsAdult = Age == AGE_ADULT; CanBlastOrSmash = HasExplosives || CanUse(RG_MEGATON_HAMMER); + //RANDOTODO replace with CanAttack and CanDamage 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); @@ -591,8 +693,6 @@ namespace Rando { 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; @@ -1021,8 +1121,6 @@ namespace Rando { CanPlantBugs = false; CanRideEpona = false; CanStunDeku = false; - CanSummonGossipFairy = false; - CanSummonGossipFairyWithoutSuns = false; //CanPlantBean = false; CanOpenBombGrotto = false; CanOpenStormGrotto = false; @@ -1099,6 +1197,7 @@ namespace Rando { AtDampeTime = false; DeliverLetter = false; TimeTravel = false; + ClearMQDCUpperLobbyRocks = false; DrainWellPast = false; DampesWindmillAccessPast = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 6a669d7ebb0..1f06d5b36db 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -260,8 +260,6 @@ class Logic { bool CanPlantBugs = false; bool CanRideEpona = false; bool CanStunDeku = false; - bool CanSummonGossipFairy = false; - bool CanSummonGossipFairyWithoutSuns = false; bool NeedNayrusLove = false; bool CanSurviveDamage = false; bool CanTakeDamage = false; @@ -357,6 +355,7 @@ class Logic { bool AtDampeTime = false; bool DeliverLetter = false; bool TimeTravel = false; + bool ClearMQDCUpperLobbyRocks = false; /* --- END OF HELPERS AND LOCATION ACCESS --- */ @@ -398,8 +397,19 @@ 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 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 CanSummonGossipFairy(); + bool CanSummonGossipFairyWithoutSuns(); + bool CanGetDekuBabaSticks(); + bool CanAttack(); + bool CanDamage(); + bool CanHitEyeTargets(); + bool CanDetonateBombFlowers(); + bool CanDetonateUprightBombFlower(); bool EventsUpdated(); uint8_t BottleCount(); void Reset(); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 066faca7eed..548440b3f47 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1789,8 +1789,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; } diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 01cddabbc86..7a3c1647bf5 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -537,16 +537,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_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_MQ_BEFORE_BOSS, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, @@ -4338,4 +4347,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/SaveManager.cpp b/soh/soh/SaveManager.cpp index 448a8d2e06f..4398d25a545 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -23,6 +23,7 @@ #include #include #include +#include extern "C" SaveContext gSaveContext; using namespace std::string_literals; @@ -1158,6 +1159,7 @@ int copy_file(const char* src, const char* dst) { // Threaded SaveFile takes copy of gSaveContext for local unmodified storage void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int sectionID) { + saveMtx.lock(); SPDLOG_INFO("Save File - fileNum: {}", fileNum); // Needed for first time save, hasn't changed in forever anyway saveBlock["version"] = 1; @@ -1232,6 +1234,7 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se InitMeta(fileNum); GameInteractor::Instance->ExecuteHooks(fileNum); SPDLOG_INFO("Save File Finish - fileNum: {}", fileNum); + saveMtx.unlock(); } // SaveSection creates a copy of gSaveContext to prevent mid-save data modification, and passes its reference to SaveFileThreaded @@ -1274,6 +1277,7 @@ void SaveManager::SaveGlobal() { } void SaveManager::LoadFile(int fileNum) { + saveMtx.lock(); SPDLOG_INFO("Load File - fileNum: {}", fileNum); std::filesystem::path fileName = GetFileName(fileNum); assert(std::filesystem::exists(fileName)); @@ -1336,6 +1340,7 @@ void SaveManager::LoadFile(int fileNum) { SohGui::RegisterPopup("Error loading save file", "A problem occurred loading the save in slot " + std::to_string(fileNum + 1) + ".\nSave file corruption is suspected.\n" + "The file has been renamed to prevent further issues."); } + saveMtx.unlock(); } void SaveManager::ThreadPoolWait() { diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 36b394a4864..599e47cf7a5 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -186,6 +186,7 @@ class SaveManager { nlohmann::json* currentJsonContext = nullptr; nlohmann::json::iterator currentJsonArrayContext; std::shared_ptr smThreadPool; + std::mutex saveMtx; }; From 255867e9227e71f738c2959728e475449ed1f66d Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:45:19 +0100 Subject: [PATCH 10/43] forgot some cleanup --- soh/soh/Enhancements/randomizer/3drando/location_access.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index b9ecd5dc916..5cf9b43ce3f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -255,7 +255,6 @@ bool BothAges(const RandomizerRegion area); bool ChildCanAccess(const RandomizerRegion area); bool AdultCanAccess(const RandomizerRegion area); bool HasAccessTo(const RandomizerRegion area); -bool HereAsSameAge(const RandomizerRegion area, ConditionFn condition); //RANDOTODO make a less stupid way to check other at same age than self referncing with this #define DAY_NIGHT_CYCLE true #define NO_DAY_NIGHT_CYCLE false From 1b51750ec04ef4ce956301eb6c636c7bda355e4d Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:26:10 +0100 Subject: [PATCH 11/43] remove a return 0 (#4347) --- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 7b6afefaaa1..5bc2b690dcd 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -280,7 +280,7 @@ void func_80A9CB18(EnKz* this, PlayState* play) { yaw -= this->actor.shape.rot.y; if ((fabsf(yaw) > 1638.0f) || (this->actor.xzDistToPlayer < 265.0f)) { this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; - return 0; + return; } this->actor.flags |= ACTOR_FLAG_TARGETABLE; From 6cd387ddf334ba73c812916f64a0a5874b69208b Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 17 Sep 2024 08:40:38 -0700 Subject: [PATCH 12/43] Fix Deku Mouth for Entrance Rando and Mido Rando Functionality (#4342) * Restore Deku Tree open as adult with dungeon shuffle. * Add Mido spawn VB to allow for preventing Mido moving in rando when starting with Zelda's letter and closed deku or forest. * Use RAND_GET_OPTION instead of OTRGlobals rando context, get rid of IS_RANDO in deku mouth VB handler. --- .../Enhancements/game-interactor/GameInteractor.h | 2 ++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 14 ++++++++++++++ soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 3523fa4057f..108d2f33e81 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 diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 4bd8da74259..92a1b278c90 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -12,6 +12,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" @@ -614,6 +615,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; @@ -1465,6 +1471,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 && diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index f55123f5b77..5567f3e29dd 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -646,7 +646,7 @@ void EnMd_Init(Actor* thisx, PlayState* play) { Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (!EnMd_ShouldSpawn(this, play)) { + if (!GameInteractor_Should(VB_MIDO_SPAWN, EnMd_ShouldSpawn(this, play), this)) { Actor_Kill(&this->actor); return; } From cd92e70b84630284f60169348d4c182a11520a6b Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:06:30 +0100 Subject: [PATCH 13/43] Refactor GetAccessibleLocations (#3871) * saving for branch change * V0 doesn't work * crashing in random places halp * push to rebase * commit for branch change * more branch switching * First apparent working * fix entrence validation * comment cleanups * post merge fixes * Fix entrences not validating when spawns/owl drops are on but other entrences are not * remove bombchusFound from the struct too * Fix issue causing improper bombchu filtering on the playthrough * text fixes * submodules pls * submodules pls pt 2 --- .../Enhancements/randomizer/3drando/fill.cpp | 630 +++++++++++------- .../Enhancements/randomizer/3drando/fill.hpp | 23 +- .../Enhancements/randomizer/3drando/hints.cpp | 6 +- .../randomizer/3drando/location_access.cpp | 7 +- .../randomizer/3drando/location_access.hpp | 4 +- .../location_access/locacc_castle_town.cpp | 5 +- soh/soh/Enhancements/randomizer/entrance.cpp | 4 +- soh/soh/Enhancements/randomizer/logic.cpp | 9 +- soh/soh/Enhancements/randomizer/logic.h | 2 +- 9 files changed, 411 insertions(+), 279 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 835055ee4a5..366fa1ed1ae 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -22,6 +22,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,12 +98,12 @@ 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) { bool ageTimePropogated = false; - //propogate childDay, childNight, adultDay, and adultNight separately + //propagate childDay, childNight, adultDay, and adultNight separately Area* parent = entrance->GetParentRegion(); Area* connection = entrance->GetConnectedRegion(); @@ -74,11 +125,10 @@ 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) { + if (propagateTimeTravel && !AreaTable(RR_ROOT)->Adult() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child()) { //RANDOTODO: sphere weirdness, other age locations not propagated in this sphere 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){ + } else if (propagateTimeTravel && !AreaTable(RR_ROOT)->Child() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult()){ AreaTable(RR_ROOT)->childDay = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultDay; AreaTable(RR_ROOT)->childNight = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; } @@ -86,55 +136,85 @@ static bool UpdateToDAccess(Entrance* entrance, SearchMode mode) { 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 && AreaTable(RR_TEMPLE_OF_TIME)->Adult()) || + (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && AreaTable(RR_TEMPLE_OF_TIME)->Child()))) { + gals.foundTempleOfTime = true; } // Condition for validating a valid starting region - if (mode == SearchMode::ValidStartingRegion) { + if (!gals.validatedStartingRegion) { 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 ((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) { + AreaTable(regionKey)->adultDay = false; + AreaTable(regionKey)->adultNight = false; } } else { - for (RandomizerRegion areaKey : areaPool) { - AreaTable(areaKey)->childDay = false; - AreaTable(areaKey)->childNight = false; + for (RandomizerRegion regionKey : gals.regionPool) { + AreaTable(regionKey)->childDay = false; + AreaTable(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 + Area* exitArea = exit.GetConnectedRegion(); + if (!exitArea->addedToPool && exit.ConditionsMet()) { + exitArea->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 +266,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 +291,230 @@ 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(); 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(); + 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) { + return true; //Return early for efficiency + } + } + 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++) { + Area* region = AreaTable(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++) { + Area* region = AreaTable(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++) { + Area* region = AreaTable(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 +522,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) { + AreaTable(RR_ROOT)->childNight = true; + AreaTable(RR_ROOT)->childDay = true; + } + } else { + for (RandomizerRegion regionKey : gals.regionPool) { + AreaTable(RR_ROOT)->adultNight = true; + AreaTable(RR_ROOT)->adultDay = true; + } } - newItemLocations.clear(); - - std::vector itemSphere; - std::list entranceSphere; + } else { + AreaTable(RR_ROOT)->childNight = true; + AreaTable(RR_ROOT)->adultNight = true; + AreaTable(RR_ROOT)->childDay = true; + AreaTable(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++) { + Area* region = AreaTable(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; + if (timePassChildDay && timePassChildNight && timePassAdultDay && timePassAdultNight) { + gals.haveTimeAccess = true; } } - //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(); - } + //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); } } - - //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 - } - } - } - } - } - - 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,25 +611,7 @@ 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){ @@ -489,7 +625,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; } } @@ -576,7 +712,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 +823,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()) { @@ -729,7 +865,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"); 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..9b22706cdc0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -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::gossipStoneLocations); //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 @@ -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){ diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 29b3cb2177c..851c26a4849 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -89,9 +89,8 @@ Area::Area(std::string regionName_, std::string scene_, RandomizerArea area, Area::~Area() = default; -bool Area::UpdateEvents(SearchMode mode) { - - if (timePass && mode != SearchMode::TimePassAccess) { +bool Area::UpdateEvents(bool haveTimeAccess) { + if (timePass && haveTimeAccess) { if (Child()) { childDay = true; childNight = true; @@ -241,7 +240,7 @@ std::shared_ptr logic; void AreaTable_Init() { using namespace Rando; randoCtx = Context::GetInstance().get(); - logic = randoCtx->GetLogic(); + logic = randoCtx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow grottoEvents = { EventAccess(&logic->GossipStoneFairy, { [] { return logic->GossipStoneFairy || logic->CanSummonGossipFairy; } }), EventAccess(&logic->ButterflyFairy, { [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); } }), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index 286551cab11..3dcdbfb2681 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -164,9 +164,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); 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..9f113218caa 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 @@ -165,7 +165,10 @@ void AreaTable_Init_CastleTown() { 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] = Area("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), diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 39eab139822..16f362cb992 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -462,7 +462,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 @@ -765,7 +765,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 diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index edb17df0c88..231799baf68 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -441,9 +441,12 @@ 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) { + if (item != ITEM_NONE && (item != ITEM_LETTER_RUTO || (item == ITEM_LETTER_RUTO && DeliverLetter))) { count++; } } @@ -492,7 +495,7 @@ namespace Rando { KokiriSword = CanUse(RG_KOKIRI_SWORD); MasterSword = CanUse(RG_MASTER_SWORD); BiggoronSword = CanUse(RG_BIGGORON_SWORD); - NumBottles = ((NoBottles) ? 0 : BottleCount()); + NumBottles = BottleCount(); HasBottle = NumBottles >= 1; Slingshot = CanUse(RG_FAIRY_SLINGSHOT) && (BuySeed || AmmoCanDrop); Ocarina = HasItem(RG_FAIRY_OCARINA); @@ -921,7 +924,7 @@ namespace Rando { //Bottle Count Bottles = 0; NumBottles = 0; - NoBottles = false; + CanEmptyBigPoes = true; //Triforce Pieces TriforcePieces = 0; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 6a669d7ebb0..d5de5f89942 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -165,7 +165,7 @@ class Logic { // Bottle Count uint8_t Bottles = 0; uint8_t NumBottles = 0; - bool NoBottles = false; + bool CanEmptyBigPoes = true; // Drops and Bottle Contents Access bool NutPot = false; From 9c11718341982b19691d3deb57a154fdabe13574 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:43:06 +0200 Subject: [PATCH 14/43] Add 146 ice trap messages (#4281) * Add ice trap message suggestions * Split messages by language * Re-run build * Apply Pepper0ni's patch with fixes --- .../Enhancements/randomizer/randomizer.cpp | 314 +++++++++++++----- soh/soh/Enhancements/randomizer/randomizer.h | 2 +- soh/soh/OTRGlobals.cpp | 6 +- 3 files changed, 241 insertions(+), 81 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index cc572629f10..4983647e92b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2826,86 +2826,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 }; @@ -3290,7 +3455,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..9942fa564e3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -20,7 +20,6 @@ #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 { @@ -68,6 +67,7 @@ class Randomizer { CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry); static void CreateCustomMessages(); static CustomMessage GetRupeeMessage(u16 rupeeTextId); + static CustomMessage GetIceTrapMessage(); static CustomMessage GetTriforcePieceMessage(); bool CheckContainsVanillaItem(RandomizerCheck randoCheck); }; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 7f15210b8de..fee872f9329 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2519,11 +2519,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { Player* player = GET_PLAYER(play); if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) { if (player->getItemEntry.getItemId == RG_ICE_TRAP) { - u16 iceTrapTextId = Random(0, NUM_ICE_TRAP_MESSAGES); - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, iceTrapTextId); - if (CVarGetInteger(CVAR_GENERAL("LetItSnow"), 0)) { - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1); - } + messageEntry = Randomizer::GetIceTrapMessage(); } else if (player->getItemEntry.getItemId == RG_TRIFORCE_PIECE) { messageEntry = Randomizer::GetTriforcePieceMessage(); } else { From 4148d59c48a694d04a987719281f002f19a92526 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 17 Sep 2024 11:32:52 -0700 Subject: [PATCH 15/43] Check Tracker Re-update (#4322) * Update check status in the check tracker to the new system. Status and Skipped are now stored in ItemLocation, though still saved separately in the trackerData section. * Fix shop checks not showing prices when identified. * Patch fix for check status bleed. Some cleanup of unused code. * Small tracker optimizations. * Fix check hiding. * Bit more cleanup. * Unhide the filter and make it work again... * Fix area totals tracking. Fix skipped status saving. * Merge conflict cleanup. --- soh/include/z64save.h | 2 +- .../Enhancements/randomizer/hook_handlers.cpp | 28 +- .../Enhancements/randomizer/item_location.cpp | 21 +- .../Enhancements/randomizer/item_location.h | 9 +- .../Enhancements/randomizer/randomizer.cpp | 2 - .../Enhancements/randomizer/randomizerTypes.h | 27 +- .../randomizer/randomizer_check_tracker.cpp | 338 +++++++----------- .../randomizer/randomizer_check_tracker.h | 12 +- soh/soh/Enhancements/randomizer/savefile.cpp | 2 +- soh/soh/SaveManager.cpp | 11 +- soh/soh/SaveManager.h | 2 + 11 files changed, 192 insertions(+), 262 deletions(-) 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/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 92a1b278c90..518daf6d081 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -306,7 +306,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; } @@ -662,7 +664,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: { @@ -1179,25 +1182,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 diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index 3185fce8aa1..d303b3c3b17 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -102,15 +102,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 { @@ -213,6 +221,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/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 4983647e92b..65144484089 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; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 507ae5fec2b..304fef213cd 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, @@ -315,6 +305,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, @@ -3886,13 +3886,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 { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d617f6fd00f..fa67fd1eb18 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); } @@ -827,33 +759,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 +803,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 +825,8 @@ void Teardown() { ClearAreaChecksAndTotals(); checksByArea.clear(); areasSpoiled = 0; + filterAreasHidden = { 0 }; + filterChecksHidden = { 0 }; lastLocationChecked = RC_UNKNOWN_CHECK; } @@ -890,30 +840,6 @@ 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::Draw() { - if (!IsVisible()) { - return; - } - DrawElement(); - // Sync up the IsVisible flag if it was changed by ImGui - SyncVisibilityConsoleVariable(); -} - void CheckTrackerWindow::DrawElement() { 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)) { @@ -985,7 +911,9 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = true; } UIWidgets::Tooltip("Clear the search field"); - checkSearch.Draw(); + if (checkSearch.Draw()) { + UpdateFilters(); + } UIWidgets::PaddedSeparator(); @@ -1039,7 +967,7 @@ void CheckTrackerWindow::DrawElement() { previousShowHidden = showHidden; doAreaScroll = true; } - if ((shouldHideFilteredAreas && ShouldHideArea(rcArea)) || + if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || (!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) ) { doDraw = false; @@ -1099,7 +1027,7 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = false; } for (auto rc : checks) { - if (doDraw && isThisAreaSpoiled && ShouldShowCheck(rc)) { + if (doDraw && isThisAreaSpoiled && !filterChecksHidden[rc]) { DrawLocation(rc); } } @@ -1119,13 +1047,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; + } } } @@ -1136,8 +1067,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())) ); } @@ -1368,6 +1300,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(); } @@ -1384,7 +1323,7 @@ void UpdateOrdering(RandomizerCheckArea rcArea) { if(checksByArea.contains(rcArea)) { std::sort(checksByArea.find(rcArea)->second.begin(), checksByArea.find(rcArea)->second.end(), CompareChecks); } - + RecalculateAllAreaTotals(); CalculateTotals(); } @@ -1393,14 +1332,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; @@ -1414,9 +1353,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; } @@ -1446,14 +1385,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; @@ -1525,11 +1458,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(); @@ -1550,9 +1485,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: @@ -1581,8 +1514,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())) { @@ -1608,8 +1541,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") { @@ -1742,12 +1674,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"); @@ -1796,7 +1728,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) { @@ -1811,8 +1743,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 295bb39b09f..3d3330f218f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -21,7 +21,6 @@ class CheckTrackerSettingsWindow : public Ship::GuiWindow { class CheckTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; - void Draw() override; ~CheckTrackerWindow() {}; protected: @@ -44,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/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 8859e8d43cb..bfa2f760607 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); } diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 4398d25a545..10e3a694b40 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -111,6 +111,7 @@ SaveManager::SaveManager() { coreSectionIDsByName["sohStats"] = SECTION_ID_STATS; coreSectionIDsByName["entrances"] = SECTION_ID_ENTRANCES; coreSectionIDsByName["scenes"] = SECTION_ID_SCENES; + coreSectionIDsByName["trackerData"] = SECTION_ID_TRACKER_DATA; AddLoadFunction("base", 1, LoadBaseVersion1); AddLoadFunction("base", 2, LoadBaseVersion2); AddLoadFunction("base", 3, LoadBaseVersion3); @@ -404,13 +405,6 @@ void SaveManager::LoadRandomizerVersion3() { // all ItemLocations is 0 anyway. randoContext->GetItemLocation(i)->SetCustomPrice(price); } - uint16_t obtained = 0; - SaveManager::Instance->LoadData("obtained", obtained, (uint16_t)0); - if (obtained) { - randoContext->GetItemLocation(i)->MarkAsObtained(); - } else { - randoContext->GetItemLocation(i)->MarkAsNotObtained(); - } }); }); @@ -496,7 +490,6 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f if (randoContext->GetItemLocation(i)->HasCustomPrice()) { SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice()); } - SaveManager::Instance->SaveData("obtained", randoContext->GetItemLocation(i)->HasObtained()); }); }); @@ -666,8 +659,8 @@ void SaveManager::Init() { if (std::filesystem::exists(GetFileName(fileNum))) { LoadFile(fileNum); saveBlock = nlohmann::json::object(); + OTRGlobals::Instance->gRandoContext->ClearItemLocations(); } - } } diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 55480b675c4..ac139ed9729 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -163,6 +163,8 @@ class SaveManager { static void LoadRandomizerVersion1(); static void LoadRandomizerVersion2(); static void LoadRandomizerVersion3(); + static void LoadTrackerData(); + static void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave); static void SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave); static void LoadBaseVersion1(); From fab63877f0baaa917f662563e04f4c2c35fef6d5 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:41:09 +0200 Subject: [PATCH 16/43] Rearrangement of the currencies in randomizer.cpp (#4338) --- .../Enhancements/randomizer/randomizer.cpp | 110 ++++++++++-------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 65144484089..01ff89d2d68 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -68,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() { From da6e4cac91cd601537fc0b82c17f6c0fc635b879 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 17 Sep 2024 14:30:33 -0500 Subject: [PATCH 17/43] Remove erroneous Entrance_OverrideBlueWarp (#4340) --- .../SkipCutscene/Story/SkipBlueWarp.cpp | 27 ++++++++++--------- .../actors/ovl_Door_Warp1/z_door_warp1.c | 15 ----------- 2 files changed, 14 insertions(+), 28 deletions(-) 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/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 00509500fe6..242ac1ddbc8 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -557,11 +557,6 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.nextCutsceneIndex = 0; } - if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || - Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { - Entrance_OverrideBlueWarp(); - } - osSyncPrintf("\n\n\nおわりおわり"); play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; @@ -654,11 +649,6 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { } play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; - if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || - Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { - Entrance_OverrideBlueWarp(); - } - play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; } @@ -847,11 +837,6 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { } } - if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || - Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) { - Entrance_OverrideBlueWarp(); - } - play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; From ee02e503fc53ee7f41d15aa8c509a069599c79fd Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 19 Sep 2024 11:15:31 -0500 Subject: [PATCH 18/43] Fix issues with faster heavy block lift (#4335) --- .../TimeSavers/FasterHeavyBlockLift.cpp | 58 +++++++++++++++++++ .../Enhancements/TimeSavers/TimeSavers.cpp | 1 + soh/soh/Enhancements/TimeSavers/TimeSavers.h | 1 + .../game-interactor/GameInteractor.h | 3 + .../Enhancements/timesaver_hook_handlers.cpp | 4 ++ .../ovl_Bg_Heavy_Block/z_bg_heavy_block.c | 36 +++++------- .../actors/ovl_player_actor/z_player.c | 18 ++---- 7 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp 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/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/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 108d2f33e81..f6db2e950a2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -244,6 +244,8 @@ typedef enum { ``` */ VB_DRAW_AMMO_COUNT, + VB_FREEZE_LINK_FOR_BLOCK_THROW, + VB_MOVE_THROWN_ACTOR, /*** Play Cutscenes ***/ @@ -286,6 +288,7 @@ typedef enum { VB_PLAY_RAINBOW_BRIDGE_CS, // Opt: *EnBox VB_PLAY_SLOW_CHEST_CS, + VB_PLAY_THROW_ANIMATION, /*** Give Items ***/ diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 0cd6ffb09d5..0682f4de13d 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -223,6 +223,10 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* if (actor->id == ACTOR_BG_MORI_HINERI) { break; } + // This is handled in the FasterHeavyBlockLift enhancement + if (actor->id == ACTOR_BG_HEAVY_BLOCK) { + break; + } RateLimitedSuccessChime(); *should = false; diff --git a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c index 61d0ccb1bc3..6df97fcfcb0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c +++ b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c @@ -7,6 +7,7 @@ #include "z_bg_heavy_block.h" #include "objects/object_heavy_object/object_heavy_object.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -320,18 +321,16 @@ void BgHeavyBlock_Wait(BgHeavyBlock* this, PlayState* play) { if (Actor_HasParent(&this->dyna.actor, play)) { this->timer = 0; - if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) { - switch (this->dyna.actor.params & 0xFF) { - case HEAVYBLOCK_BREAKABLE: - OnePointCutscene_Init(play, 4020, 270, &this->dyna.actor, MAIN_CAM); - break; - case HEAVYBLOCK_UNBREAKABLE: - OnePointCutscene_Init(play, 4021, 220, &this->dyna.actor, MAIN_CAM); - break; - case HEAVYBLOCK_UNBREAKABLE_OUTSIDE_CASTLE: - OnePointCutscene_Init(play, 4022, 210, &this->dyna.actor, MAIN_CAM); - break; - } + switch (this->dyna.actor.params & 0xFF) { + case HEAVYBLOCK_BREAKABLE: + OnePointCutscene_Init(play, 4020, 270, &this->dyna.actor, MAIN_CAM); + break; + case HEAVYBLOCK_UNBREAKABLE: + OnePointCutscene_Init(play, 4021, 220, &this->dyna.actor, MAIN_CAM); + break; + case HEAVYBLOCK_UNBREAKABLE_OUTSIDE_CASTLE: + OnePointCutscene_Init(play, 4022, 210, &this->dyna.actor, MAIN_CAM); + break; } quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 3); @@ -369,7 +368,7 @@ void BgHeavyBlock_LiftedUp(BgHeavyBlock* this, PlayState* play) { this->timer++; - if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) { + if (GameInteractor_Should(VB_FREEZE_LINK_FOR_BLOCK_THROW, true, this)) { Player_SetCsActionWithHaltedActors(play, &player->actor, 8); } @@ -408,13 +407,10 @@ void BgHeavyBlock_Fly(BgHeavyBlock* this, PlayState* play) { Quake_SetQuakeValues(quakeIndex, 14, 2, 100, 0); Quake_SetCountdown(quakeIndex, 30); - // We don't want this arbitrarily long quake with the enhancement enabled - if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) { - quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 2); - Quake_SetSpeed(quakeIndex, 12000); - Quake_SetQuakeValues(quakeIndex, 5, 0, 0, 0); - Quake_SetCountdown(quakeIndex, 999); - } + quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 2); + Quake_SetSpeed(quakeIndex, 12000); + Quake_SetQuakeValues(quakeIndex, 5, 0, 0, 0); + Quake_SetCountdown(quakeIndex, 999); SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 30, NA_SE_EV_ELECTRIC_EXPLOSION); diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index c5d1a65bd39..24ff3dd1f0c 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5096,11 +5096,7 @@ void func_8083A0F4(PlayState* play, Player* this) { anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_carryB, this->modelAnimType); } - // 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)) { - LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, 5.0f); - } else { + if (GameInteractor_Should(VB_PLAY_THROW_ANIMATION, true, anim)) { LinkAnimation_PlayOnce(play, &this->skelAnime, anim); } } @@ -9842,14 +9838,12 @@ void Player_Action_80846120(Player* this, PlayState* play) { if (LinkAnimation_OnFrame(&this->skelAnime, 229.0f)) { Actor* heldActor = this->heldActor; - if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) { - // This is the difference in rotation when the animation is sped up 5x - heldActor->shape.rot.x -= 3510; + if (GameInteractor_Should(VB_MOVE_THROWN_ACTOR, true, heldActor)) { + heldActor->speedXZ = Math_SinS(heldActor->shape.rot.x) * 40.0f; + heldActor->velocity.y = Math_CosS(heldActor->shape.rot.x) * 40.0f; + heldActor->gravity = -2.0f; + heldActor->minVelocityY = -30.0f; } - heldActor->speedXZ = Math_SinS(heldActor->shape.rot.x) * 40.0f; - heldActor->velocity.y = Math_CosS(heldActor->shape.rot.x) * 40.0f; - heldActor->gravity = -2.0f; - heldActor->minVelocityY = -30.0f; Player_DetachHeldActor(play, this); return; } From 2434eb82bf81926eaa9dff5ea1014b59626f18e8 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 19 Sep 2024 11:16:31 -0500 Subject: [PATCH 19/43] Fix for LACS awarding everywhere (#4348) * Fix for LACS awarding everywhere * Update soh/soh/Enhancements/randomizer/hook_handlers.cpp Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> --------- Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 518daf6d081..35f9df9f60f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -637,7 +637,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 = @@ -1212,6 +1216,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 || ( @@ -1225,15 +1230,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; } }); } From 74c93b0182779985b2b5f1c24bf5c866ac311df3 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 19 Sep 2024 11:17:01 -0500 Subject: [PATCH 20/43] Stop disabling dampe checkbox, as it's no longer forced to on for rando (#4349) --- soh/soh/SohMenuBar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 05f22fb2d7e..35f0b6ae141 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1094,8 +1094,7 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("All regular enemies and mini-bosses move and act twice as fast."); UIWidgets::PaddedEnhancementCheckbox("Always Win Goron Pot", CVAR_ENHANCEMENT("GoronPot"), true, false); UIWidgets::Tooltip("Always get the heart piece/purple rupee from the spinning Goron pot"); - UIWidgets::PaddedEnhancementCheckbox("Always Win Dampe Digging Game", CVAR_ENHANCEMENT("DampeWin"), true, false, SaveManager::Instance->IsRandoFile(), - "This setting is always enabled in randomizer files", UIWidgets::CheckboxGraphics::Checkmark); + UIWidgets::PaddedEnhancementCheckbox("Always Win Dampe Digging Game", CVAR_ENHANCEMENT("DampeWin"), true, false); UIWidgets::Tooltip("Always win the heart piece/purple rupee on the first dig in Dampe's grave digging game, just like in rando\nIn a rando file, this is unconditionally enabled"); UIWidgets::PaddedEnhancementCheckbox("All Dogs are Richard", CVAR_ENHANCEMENT("AllDogsRichard"), true, false); UIWidgets::Tooltip("All dogs can be traded in and will count as Richard."); From 5d8841777ac5568c83f42e055eb41eadeaea399b Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 20 Sep 2024 17:37:34 -0500 Subject: [PATCH 21/43] Fix missing despawn branch for heart containers (#4350) --- .../game-interactor/GameInteractor.h | 3 +++ .../Enhancements/randomizer/hook_handlers.cpp | 21 ++++++++++--------- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 3 ++- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index f6db2e950a2..ce5a18b6ed6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -141,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, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 35f9df9f60f..55275844336 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -689,6 +689,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; @@ -1348,16 +1359,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); diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index 5015a39083a..85a81af8573 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -6,6 +6,7 @@ #include "z_item_b_heart.h" #include "objects/object_gi_hearts/object_gi_hearts.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -39,7 +40,7 @@ static InitChainEntry sInitChain[] = { void ItemBHeart_Init(Actor* thisx, PlayState* play) { ItemBHeart* this = (ItemBHeart*)thisx; - if (Flags_GetCollectible(play, 0x1F)) { + if (GameInteractor_Should(VB_ITEM_B_HEART_DESPAWN, Flags_GetCollectible(play, 0x1F), this)) { Actor_Kill(&this->actor); } else { Actor_ProcessInitChain(&this->actor, sInitChain); From fca8081a20b7262b9a8b35ce2978feeb033e8144 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Sat, 21 Sep 2024 06:56:32 +0100 Subject: [PATCH 22/43] Fix crash when preset amount is too high (#4359) --- soh/soh/Enhancements/presets.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 ) { From 0a84d15d9dc6f30f135f4c7745c340ebcf46243d Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Sun, 22 Sep 2024 01:03:48 +0100 Subject: [PATCH 23/43] Implement some basic benchmarking for seed generation (#4353) * messy first implementation, pushing for verification * push to test other platforms, add benchmark preset * more other compiler fixes * Finish implementing benchmarks * forgot to reset the timers each run * do it better * move timers to thier own file * forgot to add files --- .../debugger/performanceTimer.cpp | 19 +++ .../Enhancements/debugger/performanceTimer.h | 38 ++++++ soh/soh/Enhancements/presets.h | 122 ++++++++++++++++++ .../Enhancements/randomizer/3drando/fill.cpp | 39 +++++- .../randomizer/3drando/location_access.cpp | 7 +- .../Enhancements/randomizer/3drando/menu.cpp | 26 ++++ .../randomizer/3drando/playthrough.cpp | 5 + soh/soh/Enhancements/randomizer/context.cpp | 1 + soh/soh/Enhancements/randomizer/context.h | 1 + soh/soh/Enhancements/randomizer/entrance.cpp | 34 ++--- soh/soh/Enhancements/randomizer/logic.cpp | 6 + 11 files changed, 281 insertions(+), 17 deletions(-) create mode 100644 soh/soh/Enhancements/debugger/performanceTimer.cpp create mode 100644 soh/soh/Enhancements/debugger/performanceTimer.h 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..ed7626326e5 --- /dev/null +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +typedef enum { + PT_WHOLE_SEED, + PT_LOGIC_RESET, + PT_AREA_RESET, + PT_UPDATE_HELPERS, + 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/presets.h b/soh/soh/Enhancements/presets.h index 39cd167c22b..5a4b2443cc3 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 { @@ -1147,6 +1148,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_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 +1337,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/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 366fa1ed1ae..a1b56c3e376 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 "../../debugger/performanceTimer.h" #include #include @@ -100,6 +101,7 @@ static void RemoveStartingItemsFromPool() { //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; @@ -133,6 +135,7 @@ static bool UpdateToDAccess(Entrance* entrance, bool propagateTimeTravel) { AreaTable(RR_ROOT)->childNight = AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; } + StopPerformanceTimer(PT_TOD_ACCESS); return ageTimePropogated; } @@ -360,6 +363,7 @@ void AddToPlaythrough(LocationAccess& locPair, GetAccessableLocationsStruct& gal // 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(); @@ -399,9 +403,11 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessableLocationsStruct& 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; } @@ -1149,6 +1155,7 @@ int Fill() { //Temporarily add shop items to the ItemPool so that entrance randomization //can validate the world using deku/hylian shields + StartPerformanceTimer(PT_ENTRANCE_SHUFFLE); AddElementsToPool(ItemPool, GetMinVanillaShopItems(32)); //assume worst case shopsanity 4 if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { SPDLOG_INFO("Shuffling Entrances..."); @@ -1162,9 +1169,12 @@ 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 + + StartPerformanceTimer(PT_SHOPSANITY); NonShopItems = {}; if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { SPDLOG_INFO("Placing Vanilla Shop Items..."); @@ -1211,7 +1221,9 @@ int Fill() { //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(); @@ -1220,7 +1232,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)) { @@ -1249,16 +1263,23 @@ 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++) { @@ -1284,19 +1305,35 @@ int Fill() { } } + 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 diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 851c26a4849..97b31e13045 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 "../../debugger/performanceTimer.h" #include @@ -91,6 +92,7 @@ Area::~Area() = default; bool Area::UpdateEvents(bool haveTimeAccess) { if (timePass && haveTimeAccess) { + StartPerformanceTimer(PT_TOD_ACCESS); if (Child()) { childDay = true; childNight = true; @@ -103,11 +105,13 @@ bool Area::UpdateEvents(bool haveTimeAccess) { AreaTable(RR_ROOT)->adultDay = true; AreaTable(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; @@ -121,6 +125,7 @@ bool Area::UpdateEvents(bool haveTimeAccess) { eventsUpdated = true; } } + StopPerformanceTimer(PT_EVENT_ACCESS); return eventsUpdated; } diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 76cf6f1bc90..ef878f5131d 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 "../../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,28 @@ 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_AREA_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 UpdateHelpers time: {}ms", GetPerformanceTimer(PT_UPDATE_HELPERS).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..fc7d7d2e0fa 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 "../../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(); + StartPerformanceTimer(PT_AREA_RESET); Areas::AccessReset(); + StopPerformanceTimer(PT_AREA_RESET); ctx->GetSettings()->FinalizeSettings(excludedLocations, enabledTricks); // once the settings have been finalized turn them into a string for hashing @@ -71,11 +74,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/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index db348b32f82..8f1ea557f4c 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -1221,4 +1221,5 @@ uint8_t Context::GetAmmo(uint32_t 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..50800363c22 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -123,6 +123,7 @@ class Context { 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; diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 16f362cb992..8610734b9ce 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 @@ -70,21 +71,24 @@ void Entrance::printAgeTimeAccess() { } bool Entrance::ConditionsMet(bool allAgeTimes) const { - - Area* parent = AreaTable(parentRegion); - int conditionsMet = 0; - - 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)); - - return conditionsMet && (!allAgeTimes || conditionsMet == 4); + auto ctx = Rando::Context::GetInstance(); + StartPerformanceTimer(PT_ENTRANCE_LOGIC); + Area* parent = AreaTable(parentRegion); + int conditionsMet = 0; + + if (allAgeTimes && !parent->AllAccess()) { + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + 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)); + + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + return conditionsMet && (!allAgeTimes || conditionsMet == 4); } uint32_t Entrance::Getuint32_t() const { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 231799baf68..ba831183291 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 @@ -455,6 +456,7 @@ namespace Rando { // Updates all logic helpers. Should be called whenever a non-helper is changed void Logic::UpdateHelpers() { + StartPerformanceTimer(PT_UPDATE_HELPERS); OcarinaButtons = (HasItem(RG_OCARINA_A_BUTTON) ? 1 : 0) + (HasItem(RG_OCARINA_C_LEFT_BUTTON) ? 1 : 0) + (HasItem(RG_OCARINA_C_RIGHT_BUTTON) ? 1 : 0) + @@ -659,6 +661,7 @@ namespace Rando { (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(); + StopPerformanceTimer(PT_UPDATE_HELPERS); } bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { @@ -776,6 +779,7 @@ namespace Rando { void Logic::Reset() { ctx->NewSaveContext(); + StartPerformanceTimer(PT_LOGIC_RESET); memset(inLogic, false, sizeof(inLogic)); //Settings-dependent variables IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || @@ -1116,5 +1120,7 @@ namespace Rando { LightTrialClearPast = false; BuyDekuShieldPast = false; TimeTravelPast = false; + + StopPerformanceTimer(PT_LOGIC_RESET); } } From 0f022011082c953c2ecab0a4c07e393c76b9a0d1 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Mon, 23 Sep 2024 17:10:29 -0700 Subject: [PATCH 24/43] SCL Consolidation, Area -> Region (#4356) * Move all `SaveContext` operations to `Logic` to prepare for encapsulation. * Rename `Area` to `Region`, `areaTable` to `regionTable`, and all local variables named variants of area to region that were of the `RandomizerRegion` or `Region` types. * Fix mistaken renames. * Rename PT_AREA_RESET to PT_REGION_RESET after rebasing on performance timer commit. Change include path for the timer to absolute rather than relative. --- .../Enhancements/debugger/performanceTimer.h | 2 +- .../Enhancements/randomizer/3drando/fill.cpp | 82 +- .../randomizer/3drando/location_access.cpp | 210 ++-- .../randomizer/3drando/location_access.hpp | 66 +- .../locacc_bottom_of_the_well.cpp | 10 +- .../location_access/locacc_castle_town.cpp | 54 +- .../location_access/locacc_death_mountain.cpp | 46 +- .../location_access/locacc_deku_tree.cpp | 48 +- .../locacc_dodongos_cavern.cpp | 62 +- .../location_access/locacc_fire_temple.cpp | 90 +- .../location_access/locacc_forest_temple.cpp | 84 +- .../location_access/locacc_ganons_castle.cpp | 38 +- .../locacc_gerudo_training_grounds.cpp | 36 +- .../location_access/locacc_gerudo_valley.cpp | 40 +- .../location_access/locacc_hyrule_field.cpp | 42 +- .../location_access/locacc_ice_cavern.cpp | 16 +- .../locacc_jabujabus_belly.cpp | 50 +- .../location_access/locacc_kakariko.cpp | 54 +- .../location_access/locacc_lost_woods.cpp | 46 +- .../location_access/locacc_shadow_temple.cpp | 34 +- .../location_access/locacc_spirit_temple.cpp | 44 +- .../location_access/locacc_water_temple.cpp | 72 +- .../location_access/locacc_zoras_domain.cpp | 26 +- .../Enhancements/randomizer/3drando/menu.cpp | 4 +- .../randomizer/3drando/playthrough.cpp | 8 +- .../randomizer/3drando/spoiler_log.cpp | 2 +- soh/soh/Enhancements/randomizer/context.cpp | 776 --------------- soh/soh/Enhancements/randomizer/context.h | 34 - soh/soh/Enhancements/randomizer/entrance.cpp | 46 +- soh/soh/Enhancements/randomizer/entrance.h | 4 +- soh/soh/Enhancements/randomizer/item.cpp | 36 +- soh/soh/Enhancements/randomizer/logic.cpp | 914 ++++++++++++++++-- soh/soh/Enhancements/randomizer/logic.h | 33 +- .../randomizer/randomizer_check_tracker.cpp | 2 +- soh/soh/SaveManager.cpp | 2 +- 35 files changed, 1554 insertions(+), 1559 deletions(-) diff --git a/soh/soh/Enhancements/debugger/performanceTimer.h b/soh/soh/Enhancements/debugger/performanceTimer.h index ed7626326e5..842bd91c61c 100644 --- a/soh/soh/Enhancements/debugger/performanceTimer.h +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -7,7 +7,7 @@ typedef enum { PT_WHOLE_SEED, PT_LOGIC_RESET, - PT_AREA_RESET, + PT_REGION_RESET, PT_UPDATE_HELPERS, PT_SPOILER_LOG, PT_ENTRANCE_SHUFFLE, diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index a1b56c3e376..2a6f3ed088c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -14,7 +14,7 @@ #include "pool_functions.hpp" //#include "debug.hpp" #include "soh/Enhancements/randomizer/static_data.h" -#include "../../debugger/performanceTimer.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include @@ -106,8 +106,8 @@ static bool UpdateToDAccess(Entrance* entrance, bool propagateTimeTravel) { bool ageTimePropogated = false; //propagate childDay, childNight, adultDay, and adultNight separately - Area* parent = entrance->GetParentRegion(); - Area* connection = entrance->GetConnectedRegion(); + Region* parent = entrance->GetParentRegion(); + Region* connection = entrance->GetConnectedRegion(); if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { connection->childDay = true; @@ -127,12 +127,12 @@ static bool UpdateToDAccess(Entrance* entrance, bool propagateTimeTravel) { } //special check for temple of time - if (propagateTimeTravel && !AreaTable(RR_ROOT)->Adult() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child()) { //RANDOTODO: sphere weirdness, other age locations not propagated in this sphere - 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 (propagateTimeTravel && !AreaTable(RR_ROOT)->Child() && AreaTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult()){ - 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); @@ -143,17 +143,17 @@ static bool UpdateToDAccess(Entrance* entrance, bool propagateTimeTravel) { static void ValidateOtherEntrance(GetAccessableLocationsStruct& gals) { auto ctx = Rando::Context::GetInstance(); // Condition for validating Temple of Time Access - if (!gals.foundTempleOfTime && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && AreaTable(RR_TEMPLE_OF_TIME)->Adult()) || - (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && AreaTable(RR_TEMPLE_OF_TIME)->Child()))) { + 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 (!gals.validatedStartingRegion) { - 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(); + 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(); - Area* kokiri = AreaTable(RR_KOKIRI_FOREST); - Area* kakariko = AreaTable(RR_KAKARIKO_VILLAGE); + 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()))) { @@ -183,13 +183,13 @@ static void ValidateSphereZero(GetAccessableLocationsStruct& gals){ // Reset access as the non-starting age if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { for (RandomizerRegion regionKey : gals.regionPool) { - AreaTable(regionKey)->adultDay = false; - AreaTable(regionKey)->adultNight = false; + RegionTable(regionKey)->adultDay = false; + RegionTable(regionKey)->adultNight = false; } } else { for (RandomizerRegion regionKey : gals.regionPool) { - AreaTable(regionKey)->childDay = false; - AreaTable(regionKey)->childNight = false; + RegionTable(regionKey)->childDay = false; + RegionTable(regionKey)->childNight = false; } } gals.sphereZeroComplete = true; @@ -210,9 +210,9 @@ void ProcessExit(Entrance& exit, GetAccessableLocationsStruct& gals, bool propag } //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; + Region* exitRegion = exit.GetConnectedRegion(); + if (!exitRegion->addedToPool && exit.ConditionsMet()) { + exitRegion->addedToPool = true; gals.regionPool.push_back(exit.GetConnectedRegionKey()); } } @@ -306,7 +306,7 @@ void ResetLogic(std::shared_ptr& ctx, bool applyInventory = false){ if (applyInventory){ ApplyStartingInventory(); } - Areas::AccessReset(); + Regions::AccessReset(); ctx->LocationReset(); } @@ -419,7 +419,7 @@ std::vector ReachabilitySearch(const std::vector 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { gals.InitLoop(); for (size_t i = 0; i < gals.regionPool.size(); i++) { - Area* region = AreaTable(gals.regionPool[i]); + Region* region = RegionTable(gals.regionPool[i]); if (region->UpdateEvents()){ gals.updatedEvents = true; @@ -454,7 +454,7 @@ void GeneratePlaythrough() { while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { gals.InitLoop(); for (size_t i = 0; i < gals.regionPool.size(); i++) { - Area* region = AreaTable(gals.regionPool[i]); + Region* region = RegionTable(gals.regionPool[i]); if (region->UpdateEvents()){ gals.updatedEvents = true; @@ -496,7 +496,7 @@ bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) { while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { gals.InitLoop(); for (size_t i = 0; i < gals.regionPool.size(); i++) { - Area* region = AreaTable(gals.regionPool[i]); + Region* region = RegionTable(gals.regionPool[i]); if (region->UpdateEvents()){ gals.updatedEvents = true; @@ -541,26 +541,26 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce //if we assume valid sphere zero, we only want starting age access if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { for (RandomizerRegion regionKey : gals.regionPool) { - AreaTable(RR_ROOT)->childNight = true; - AreaTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->childDay = true; } } else { for (RandomizerRegion regionKey : gals.regionPool) { - AreaTable(RR_ROOT)->adultNight = true; - AreaTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultDay = true; } } } else { - AreaTable(RR_ROOT)->childNight = true; - AreaTable(RR_ROOT)->adultNight = true; - AreaTable(RR_ROOT)->childDay = true; - AreaTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->adultDay = true; } while (gals.newItemLocations.size() > 0 || gals.updatedEvents || gals.ageTimePropogated || gals.firstIteration) { gals.InitLoop(); for (size_t i = 0; i < gals.regionPool.size(); i++) { - Area* region = AreaTable(gals.regionPool[i]); + Region* region = RegionTable(gals.regionPool[i]); if (region->UpdateEvents(gals.haveTimeAccess)){ gals.updatedEvents = true; @@ -620,7 +620,7 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce } } -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(); @@ -642,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)}; @@ -839,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 @@ -1109,7 +1109,7 @@ static void RandomizeLinksPocket() { void VanillaFill() { auto ctx = Rando::Context::GetInstance(); //Perform minimum needed initialization - AreaTable_Init(); + RegionTable_Init(); ctx->GenerateLocationPool(); GenerateItemPool(); GenerateStartingInventory(); @@ -1145,7 +1145,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(); @@ -1339,7 +1339,7 @@ int Fill() { //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/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 97b31e13045..33ef7ccbd36 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -7,7 +7,7 @@ #include "spoiler_log.hpp" #include "../trial.h" #include "../entrance.h" -#include "../../debugger/performanceTimer.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include @@ -31,7 +31,7 @@ bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const { 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)) || @@ -74,8 +74,8 @@ bool LocationAccess::CanBuy() const { 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_, @@ -88,22 +88,22 @@ 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(bool haveTimeAccess) { +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); } @@ -129,18 +129,18 @@ bool Area::UpdateEvents(bool haveTimeAccess) { 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(); @@ -149,22 +149,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; @@ -186,7 +186,7 @@ bool Area::AllAccountedFor() const { return AllAccess(); } -bool Area::CheckAllAccess(const RandomizerRegion exitKey) { +bool Region::CheckAllAccess(const RandomizerRegion exitKey) { if (!AllAccess()) { return false; } @@ -202,7 +202,7 @@ bool Area::CheckAllAccess(const RandomizerRegion exitKey) { return false; } -void Area::ResetVariables() { +void Region::ResetVariables() { childDay = false; childNight = false; adultDay = false; @@ -213,36 +213,36 @@ 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].HereCheck(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; std::shared_ptr logic; -void AreaTable_Init() { +void RegionTable_Init() { using namespace Rando; randoCtx = Context::GetInstance().get(); logic = randoCtx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow @@ -254,10 +254,10 @@ void AreaTable_Init() { }; //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), @@ -267,7 +267,7 @@ void AreaTable_Init() { 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;}}), @@ -279,67 +279,67 @@ void AreaTable_Init() { 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++) { @@ -398,41 +398,41 @@ std::string CleanCheckConditionString(std::string condition) { 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; } } } @@ -440,10 +440,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(); } @@ -451,23 +451,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; } } @@ -483,24 +483,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"; @@ -524,20 +524,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); } @@ -548,8 +548,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 3dcdbfb2681..d2e060c8454 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -136,15 +136,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; @@ -246,20 +246,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); +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 +267,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..864ca8785dc 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,11 +4,11 @@ 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;}}), @@ -19,7 +19,7 @@ void AreaTable_Init_BottomOfTheWell() { | 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, { + 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;}}), @@ -52,7 +52,7 @@ 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, { + 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;}}), }, { @@ -69,7 +69,7 @@ void AreaTable_Init_BottomOfTheWell() { //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)), 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 9f113218caa..d59be83605c 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,7 +33,7 @@ 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;}}), }, { @@ -48,7 +48,7 @@ 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_ALTAR_HINT_CHILD, logic->IsChild), @@ -60,7 +60,7 @@ void AreaTable_Init_CastleTown() { 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)));}}), }); - 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;}}), }, { @@ -73,14 +73,14 @@ void AreaTable_Init_CastleTown() { 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->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), @@ -99,7 +99,7 @@ void AreaTable_Init_CastleTown() { Entrance(RR_HC_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - 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,7 +118,7 @@ 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);}}), @@ -132,7 +132,7 @@ void AreaTable_Init_CastleTown() { 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, { + 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 @@ -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,20 @@ 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;}}), }, { @@ -177,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), @@ -192,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->MaskOfTruth, {[]{return logic->MaskOfTruth || (logic->SkullMask && (randoCtx->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->HasAllStones)));}}), }, { LOCATION(RC_MASK_SHOP_HINT, true), }, { @@ -203,7 +203,7 @@ 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), }, { @@ -211,7 +211,7 @@ void AreaTable_Init_CastleTown() { 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);}}), }, { @@ -223,7 +223,7 @@ void AreaTable_Init_CastleTown() { 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), @@ -238,7 +238,7 @@ 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)))), @@ -257,7 +257,7 @@ void AreaTable_Init_CastleTown() { 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), @@ -272,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), }, { @@ -280,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..1b99ea43aca 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,9 +3,9 @@ using namespace Rando; -void AreaTable_Init_DeathMountain() { +void RegionTable_Init_DeathMountain() { auto ctx = Rando::Context::GetInstance(); - areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Area("Death Mountain", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { + 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));}}), }, { @@ -24,7 +24,7 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_DMT_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - 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;}}), @@ -45,12 +45,12 @@ void AreaTable_Init_DeathMountain() { Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->CanBlastOrSmash;});}}), }); - 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), @@ -60,7 +60,7 @@ void AreaTable_Init_DeathMountain() { }); - 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), @@ -72,7 +72,7 @@ void AreaTable_Init_DeathMountain() { 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,7 +80,7 @@ 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->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), @@ -111,7 +111,7 @@ void AreaTable_Init_DeathMountain() { 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)));}}), }); - 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));}}), }, {}, { @@ -120,7 +120,7 @@ void AreaTable_Init_DeathMountain() { 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 +132,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));}}), }); - 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,7 +153,7 @@ 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), @@ -164,14 +164,14 @@ void AreaTable_Init_DeathMountain() { 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_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);});}}) }); - 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));}}), }, { @@ -187,7 +187,7 @@ void AreaTable_Init_DeathMountain() { 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), }, { @@ -196,7 +196,7 @@ void AreaTable_Init_DeathMountain() { 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));}}), }); - 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_GC_DARUNIAS_CHAMBER, {[]{return true;}}), @@ -204,7 +204,7 @@ void AreaTable_Init_DeathMountain() { 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;}}), @@ -212,7 +212,7 @@ void AreaTable_Init_DeathMountain() { 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;}}), }); - 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)), @@ -221,7 +221,7 @@ void AreaTable_Init_DeathMountain() { 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));}}), }, { @@ -235,7 +235,7 @@ void AreaTable_Init_DeathMountain() { 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);}}), }); - 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,7 +243,7 @@ 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), @@ -255,7 +255,7 @@ void AreaTable_Init_DeathMountain() { 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), 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 492a226f4be..1c2f55ab632 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,11 +4,11 @@ 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();}}), @@ -19,7 +19,7 @@ void AreaTable_Init_DekuTree() { | 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, { + 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));}}), @@ -36,13 +36,13 @@ void AreaTable_Init_DekuTree() { 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);});}}), }); - 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,7 +51,7 @@ 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));}}), @@ -66,7 +66,7 @@ void AreaTable_Init_DekuTree() { 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->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));}, @@ -84,25 +84,25 @@ void AreaTable_Init_DekuTree() { 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);}}), }); - 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_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));}}), @@ -112,7 +112,7 @@ void AreaTable_Init_DekuTree() { 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);}) && @@ -125,7 +125,7 @@ void AreaTable_Init_DekuTree() { 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), }, { @@ -133,7 +133,7 @@ void AreaTable_Init_DekuTree() { 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));}}), @@ -144,7 +144,7 @@ void AreaTable_Init_DekuTree() { 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));});}}), }); - 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;});}}), @@ -155,7 +155,7 @@ void AreaTable_Init_DekuTree() { | 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, { + 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));}}), @@ -176,7 +176,7 @@ void AreaTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return randoCtx->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 && @@ -188,7 +188,7 @@ void AreaTable_Init_DekuTree() { 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), }, { @@ -198,7 +198,7 @@ void AreaTable_Init_DekuTree() { 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)), }, { @@ -210,7 +210,7 @@ void AreaTable_Init_DekuTree() { 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), @@ -220,7 +220,7 @@ void AreaTable_Init_DekuTree() { 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), }, { @@ -232,7 +232,7 @@ void AreaTable_Init_DekuTree() { }); 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; }}), @@ -244,7 +244,7 @@ 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(); } }), @@ -253,7 +253,7 @@ void AreaTable_Init_DekuTree() { }); 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, { [] { 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 591705e51fc..7982c942f0b 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,11 +4,11 @@ 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();}}), @@ -19,13 +19,13 @@ void AreaTable_Init_DodongosCavern() { | 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, {}, {}, { + 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;});}}), }); - 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;}));}}), }, { @@ -44,13 +44,13 @@ void AreaTable_Init_DodongosCavern() { 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))), }, { @@ -60,7 +60,7 @@ void AreaTable_Init_DodongosCavern() { 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), }, { @@ -68,13 +68,13 @@ void AreaTable_Init_DodongosCavern() { 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;});}}), @@ -82,14 +82,14 @@ void AreaTable_Init_DodongosCavern() { 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_LOWER_LIZALFOS, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_NEAR_DODONGO_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_DODONGO_ROOM, []{return logic->CanBlastOrSmash || logic->GoronBracelet;});}}), }); - 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), }, { @@ -97,14 +97,14 @@ void AreaTable_Init_DodongosCavern() { 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;});}}), }); - 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))), @@ -114,7 +114,7 @@ void AreaTable_Init_DodongosCavern() { 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), }, { @@ -122,13 +122,13 @@ void AreaTable_Init_DodongosCavern() { 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;}}), }); - 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), }, { @@ -138,7 +138,7 @@ void AreaTable_Init_DodongosCavern() { 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));}}), }); - 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), @@ -147,13 +147,13 @@ void AreaTable_Init_DodongosCavern() { 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);}}), }); - 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) || @@ -162,13 +162,13 @@ void AreaTable_Init_DodongosCavern() { 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);}}), }); - 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,7 +178,7 @@ 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;})), }, { @@ -187,7 +187,7 @@ void AreaTable_Init_DodongosCavern() { 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;}}), }, {}, { @@ -197,7 +197,7 @@ void AreaTable_Init_DodongosCavern() { 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), }, { @@ -210,13 +210,13 @@ 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, {}, {}, { + 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;});}}), }); - 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->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->IsAdult || logic->KokiriSword || logic->Boomerang);}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairy;}}), @@ -242,7 +242,7 @@ void AreaTable_Init_DodongosCavern() { //Trick: logic->HasExplosives || (LogicDCMQEyes && logic->GoronBracelet && (logic->IsAdult || LogicDCMQChildBack) && ((logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (LogicDCJump || logic->Hammer || logic->HoverBoots || logic->Hookshot)))) }); - 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->CanStunDeku), }, { @@ -252,7 +252,7 @@ void AreaTable_Init_DodongosCavern() { logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT);}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA] = Area("Dodongos Cavern MQ Bomb Bag Area", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA] = Region("Dodongos Cavern MQ Bomb Bag Region", "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_BOMB_BAG_AREA, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW);}) || logic->GoronBracelet || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives) && logic->HookshotOrBoomerang), @@ -261,7 +261,7 @@ void AreaTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_BOSS_AREA] = Area("Dodongos Cavern MQ BossArea", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_DODONGOS_CAVERN_MQ_BOSS_AREA] = Region("Dodongos Cavern MQ BossArea", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { @@ -278,7 +278,7 @@ void AreaTable_Init_DodongosCavern() { | 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(); } }), @@ -287,7 +287,7 @@ void AreaTable_Init_DodongosCavern() { }); 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, 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..e888f26d22a 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,11 +4,11 @@ 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();}}), @@ -19,7 +19,7 @@ void AreaTable_Init_FireTemple() { | 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, {}, { + 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;}}), @@ -29,7 +29,7 @@ void AreaTable_Init_FireTemple() { 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));}}), }, { @@ -41,13 +41,13 @@ void AreaTable_Init_FireTemple() { 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));}}), }); - 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), }, { @@ -56,7 +56,7 @@ void AreaTable_Init_FireTemple() { 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), }, { @@ -66,7 +66,7 @@ void AreaTable_Init_FireTemple() { 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,13 +84,13 @@ 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;}}), @@ -99,7 +99,7 @@ void AreaTable_Init_FireTemple() { 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,7 +107,7 @@ 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), }, { @@ -115,7 +115,7 @@ void AreaTable_Init_FireTemple() { 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,13 +123,13 @@ 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);}}), }); - 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;})), }, { @@ -139,13 +139,13 @@ void AreaTable_Init_FireTemple() { 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));}}), }); - 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)), @@ -157,7 +157,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,7 +165,7 @@ 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_BOULDER_MAZE_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 8);}}), @@ -173,7 +173,7 @@ void AreaTable_Init_FireTemple() { 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_MAP_AREA, {[]{return logic->IsAdult;}}), @@ -181,7 +181,7 @@ void AreaTable_Init_FireTemple() { 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,7 +189,7 @@ 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), }, { @@ -200,7 +200,7 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return logic->CanUse(RG_SCARECROW) || (randoCtx->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)), }, { @@ -209,7 +209,7 @@ void AreaTable_Init_FireTemple() { 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), @@ -219,13 +219,13 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->CanTakeDamage;}}), }); - 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);}}), @@ -234,14 +234,14 @@ void AreaTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return randoCtx->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,7 +249,7 @@ 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);})), }, { @@ -259,21 +259,21 @@ 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;}}), }); - 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) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), @@ -281,13 +281,13 @@ void AreaTable_Init_FireTemple() { 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;}}), }); - 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), }, { @@ -297,12 +297,12 @@ void AreaTable_Init_FireTemple() { 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);}}), @@ -313,7 +313,7 @@ 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, {}, { + 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)))))), @@ -326,7 +326,7 @@ void AreaTable_Init_FireTemple() { 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;}}), }, { @@ -335,7 +335,7 @@ void AreaTable_Init_FireTemple() { 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) @@ -352,7 +352,7 @@ void AreaTable_Init_FireTemple() { //Trick: logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource || (LogicFireMQClimb && logic->HoverBoots)) }); - 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))), @@ -363,7 +363,7 @@ void AreaTable_Init_FireTemple() { //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(&logic->FairyPot, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), @@ -377,7 +377,7 @@ void AreaTable_Init_FireTemple() { 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)), //Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze @@ -395,7 +395,7 @@ 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; } }), @@ -404,7 +404,7 @@ void AreaTable_Init_FireTemple() { }); 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, 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..5619560dc83 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,11 +4,11 @@ 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();}}), @@ -19,7 +19,7 @@ void AreaTable_Init_ForestTemple() { | 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, {}, { + 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)))), @@ -29,13 +29,13 @@ void AreaTable_Init_ForestTemple() { 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);}}), }); - 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));}}), }, { @@ -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,7 +70,7 @@ 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));}}), @@ -86,7 +86,7 @@ void AreaTable_Init_ForestTemple() { 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));}}), @@ -98,7 +98,7 @@ 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));}}), @@ -114,7 +114,7 @@ void AreaTable_Init_ForestTemple() { 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));}}), @@ -125,7 +125,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return randoCtx->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));})), }, { @@ -134,7 +134,7 @@ void AreaTable_Init_ForestTemple() { 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,12 +143,12 @@ 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));});}}), }); - 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), }, { @@ -156,13 +156,13 @@ void AreaTable_Init_ForestTemple() { 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);}}), }); - 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))), }, { @@ -173,13 +173,13 @@ void AreaTable_Init_ForestTemple() { 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);}}), }); - 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,13 +257,13 @@ 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);}}), }); - 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), @@ -278,7 +278,7 @@ void AreaTable_Init_ForestTemple() { | 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, {}, { + 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), @@ -288,7 +288,7 @@ void AreaTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAdultAttack || logic->CanChildAttack || 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;}}), }, { @@ -306,7 +306,7 @@ void AreaTable_Init_ForestTemple() { 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)), }, { @@ -317,7 +317,7 @@ void AreaTable_Init_ForestTemple() { 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), }, { @@ -325,7 +325,7 @@ void AreaTable_Init_ForestTemple() { 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), }, { @@ -335,7 +335,7 @@ void AreaTable_Init_ForestTemple() { 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));}}), @@ -350,7 +350,7 @@ 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), }, { @@ -360,7 +360,7 @@ void AreaTable_Init_ForestTemple() { //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,7 +393,7 @@ 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), }, { @@ -406,7 +406,7 @@ 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; } }), @@ -414,7 +414,7 @@ void AreaTable_Init_ForestTemple() { 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..e5aba3db9af 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,11 +5,11 @@ 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();}}), @@ -20,7 +20,7 @@ void AreaTable_Init_GanonsCastle() { | 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, {}, { + 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), }, { @@ -41,7 +41,7 @@ void AreaTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return randoCtx->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;}}), }, { @@ -52,7 +52,7 @@ void AreaTable_Init_GanonsCastle() { 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);}}), }, { @@ -60,12 +60,12 @@ void AreaTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanAdultDamage || logic->CanChildDamage), }, {}); - 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;}}), @@ -76,7 +76,7 @@ void AreaTable_Init_GanonsCastle() { 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))))));}}), }, { @@ -85,7 +85,7 @@ void AreaTable_Init_GanonsCastle() { 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));}}), @@ -95,7 +95,7 @@ void AreaTable_Init_GanonsCastle() { 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))), }, {}); - 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));}}), }, { @@ -111,7 +111,7 @@ void AreaTable_Init_GanonsCastle() { }, {}); } - 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))), @@ -122,7 +122,7 @@ void AreaTable_Init_GanonsCastle() { | 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, {}, { + 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), }, { @@ -143,7 +143,7 @@ void AreaTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return randoCtx->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;}}), }, { @@ -155,7 +155,7 @@ void AreaTable_Init_GanonsCastle() { 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);}}), }, { @@ -165,13 +165,13 @@ void AreaTable_Init_GanonsCastle() { 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))) }, {}, {}); - 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);}}), @@ -180,7 +180,7 @@ void AreaTable_Init_GanonsCastle() { 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))) @@ -191,7 +191,7 @@ void AreaTable_Init_GanonsCastle() { //Trick: logic->IsAdult && logic->Bow && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HoverBoots || (logic->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))));}}), @@ -205,7 +205,7 @@ void AreaTable_Init_GanonsCastle() { 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)))), }, {}); - 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) 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..030b05f9894 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,11 +4,11 @@ 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();}}), @@ -19,7 +19,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { | 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, {}, { + 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)), @@ -33,7 +33,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 4)), @@ -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,7 +56,7 @@ 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), }, { @@ -65,7 +65,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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))), @@ -75,7 +75,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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,7 +91,7 @@ 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), }, { @@ -100,7 +100,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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);}}), }); - 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), @@ -113,7 +113,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { | 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, {}, { + 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), @@ -128,7 +128,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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));}}), }, { @@ -139,12 +139,12 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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));}}), }); - 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), }, {}); - 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), }, { @@ -153,7 +153,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { //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;}}), }, { @@ -166,7 +166,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { //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)), @@ -177,7 +177,7 @@ void AreaTable_Init_GerudoTrainingGrounds() { 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), 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..d5623fe1715 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,8 +3,8 @@ 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;}}), }, { @@ -19,7 +19,7 @@ void AreaTable_Init_GerudoValley() { 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));}}), }); - 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->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), @@ -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 }); - 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,7 +54,7 @@ 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);}}), }, { @@ -73,17 +73,17 @@ void AreaTable_Init_GerudoValley() { 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), @@ -93,7 +93,7 @@ void AreaTable_Init_GerudoValley() { 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;}}), @@ -118,7 +118,7 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_GF_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormGrotto;}}), }); - 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*/);}}), }, {}, { @@ -127,7 +127,7 @@ void AreaTable_Init_GerudoValley() { 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,13 +135,13 @@ 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);}}), }); - 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;}}), @@ -157,13 +157,13 @@ void AreaTable_Init_GerudoValley() { Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || randoCtx->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;}}), }); - 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;}}), @@ -182,7 +182,7 @@ void AreaTable_Init_GerudoValley() { 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,7 +198,7 @@ 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), 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..a6ef9a58fb6 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,8 +3,8 @@ 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;}}), }, { @@ -30,7 +30,7 @@ void AreaTable_Init_HyruleField() { 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), @@ -42,7 +42,7 @@ void AreaTable_Init_HyruleField() { 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), @@ -54,7 +54,7 @@ void AreaTable_Init_HyruleField() { 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), @@ -63,7 +63,7 @@ void AreaTable_Init_HyruleField() { 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)), @@ -73,7 +73,7 @@ void AreaTable_Init_HyruleField() { 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), @@ -85,7 +85,7 @@ void AreaTable_Init_HyruleField() { 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,7 +93,7 @@ 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), }, { @@ -101,7 +101,7 @@ void AreaTable_Init_HyruleField() { 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)), }, { @@ -109,7 +109,7 @@ void AreaTable_Init_HyruleField() { 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->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}), @@ -140,18 +140,18 @@ void AreaTable_Init_HyruleField() { 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)));}}), }, { @@ -165,7 +165,7 @@ 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), @@ -209,7 +209,7 @@ void AreaTable_Init_HyruleField() { 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), @@ -220,7 +220,7 @@ void AreaTable_Init_HyruleField() { 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);}}), @@ -240,7 +240,7 @@ 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), }, { @@ -248,7 +248,7 @@ void AreaTable_Init_HyruleField() { 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,7 +267,7 @@ 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), 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..7e603d6572d 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,11 +4,11 @@ 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;}}), @@ -19,13 +19,13 @@ void AreaTable_Init_IceCavern() { | 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, {}, {}, { + 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);});}}), }); - 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);}}), }, { @@ -45,7 +45,7 @@ void AreaTable_Init_IceCavern() { | 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, { + 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;}}), }, {}, { @@ -56,7 +56,7 @@ void AreaTable_Init_IceCavern() { 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);}}), }, { @@ -64,7 +64,7 @@ void AreaTable_Init_IceCavern() { 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))), @@ -73,7 +73,7 @@ void AreaTable_Init_IceCavern() { //Tricks: (logic->CanUse(RG_SCARECROW) || (logic->HoverBoots && 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), 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..b0d6031a962 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,11 +4,11 @@ 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();}}), @@ -19,13 +19,13 @@ void AreaTable_Init_JabuJabusBelly() { | 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, {}, {}, { + 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;}}), }); - 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;}}), @@ -33,7 +33,7 @@ void AreaTable_Init_JabuJabusBelly() { 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));}}), }); - 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,7 +41,7 @@ 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), @@ -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;}}), }, { @@ -64,7 +64,7 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return logic->Swim && 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,7 +72,7 @@ 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), }, { @@ -81,7 +81,7 @@ void AreaTable_Init_JabuJabusBelly() { 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,7 +107,7 @@ 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), }, { @@ -115,23 +115,23 @@ void AreaTable_Init_JabuJabusBelly() { 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,13 +140,13 @@ 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), }, { @@ -160,7 +160,7 @@ void AreaTable_Init_JabuJabusBelly() { | 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, { + 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;}}), }, { @@ -173,7 +173,7 @@ 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)), @@ -191,7 +191,7 @@ void AreaTable_Init_JabuJabusBelly() { 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))), @@ -202,7 +202,7 @@ void AreaTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->KokiriSword);}}), }); - 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;}}), }, { @@ -221,7 +221,7 @@ 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(); } }), @@ -230,7 +230,7 @@ void AreaTable_Init_JabuJabusBelly() { }); 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, 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..c7b57db8412 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -3,8 +3,8 @@ 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;}}), @@ -39,13 +39,13 @@ void AreaTable_Init_Kakariko() { 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)), }, { @@ -54,7 +54,7 @@ void AreaTable_Init_Kakariko() { 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,7 +70,7 @@ 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);}}), }, {}, { @@ -78,7 +78,7 @@ void AreaTable_Init_Kakariko() { 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), @@ -91,13 +91,13 @@ void AreaTable_Init_Kakariko() { 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,12 +106,12 @@ 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));}}), }, { @@ -124,7 +124,7 @@ void AreaTable_Init_Kakariko() { 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,7 +139,7 @@ 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), }, { @@ -147,7 +147,7 @@ void AreaTable_Init_Kakariko() { 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,14 +163,14 @@ 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, { [] { @@ -186,7 +186,7 @@ void AreaTable_Init_Kakariko() { 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,7 +194,7 @@ 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), @@ -206,7 +206,7 @@ void AreaTable_Init_Kakariko() { 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));}}), @@ -228,7 +228,7 @@ void AreaTable_Init_Kakariko() { 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,7 +245,7 @@ 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)), @@ -254,7 +254,7 @@ void AreaTable_Init_Kakariko() { 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));}}), @@ -268,7 +268,7 @@ void AreaTable_Init_Kakariko() { 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,7 +276,7 @@ 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;}}), }, { @@ -288,7 +288,7 @@ void AreaTable_Init_Kakariko() { 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));}}), }); - 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_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..f4875de97ed 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,8 +3,8 @@ 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;}}), @@ -30,7 +30,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_KF_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - 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))));}}), @@ -45,7 +45,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy("Big Skulltula") || logic->ForestTempleClear)) || randoCtx->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,7 +94,7 @@ 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), @@ -106,12 +106,12 @@ void AreaTable_Init_LostWoods() { 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->PoachersSawAccess, {[]{return logic->PoachersSawAccess || (logic->IsAdult && logic->OddPoulticeAccess);}}), @@ -146,7 +146,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, {[]{return Here(RR_THE_LOST_WOODS, []{return logic->CanBlastOrSmash;});}}), }); - 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);}}), }, { @@ -164,7 +164,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_LW_SCRUBS_GROTTO, {[]{return Here(RR_LW_BEYOND_MIDO, []{return logic->CanBlastOrSmash;});}}), }); - 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), @@ -176,7 +176,7 @@ void AreaTable_Init_LostWoods() { 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,7 +185,7 @@ 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), @@ -195,14 +195,14 @@ void AreaTable_Init_LostWoods() { 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;}}), }); - 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;}}), }, { @@ -221,7 +221,7 @@ void AreaTable_Init_LostWoods() { Entrance(RR_SFM_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - 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,7 +229,7 @@ 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? }, { @@ -237,7 +237,7 @@ void AreaTable_Init_LostWoods() { 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), @@ -247,7 +247,7 @@ void AreaTable_Init_LostWoods() { 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..82c5e1e4b51 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,11 +4,11 @@ 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));}}), @@ -19,7 +19,7 @@ void AreaTable_Init_ShadowTemple() { | 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, { + areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", "Shadow Temple", RA_SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), }, { @@ -32,7 +32,7 @@ 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 }, { @@ -46,7 +46,7 @@ void AreaTable_Init_ShadowTemple() { 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), @@ -63,7 +63,7 @@ void AreaTable_Init_ShadowTemple() { 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);}}), }); - 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), @@ -74,7 +74,7 @@ void AreaTable_Init_ShadowTemple() { 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)), @@ -90,7 +90,7 @@ void AreaTable_Init_ShadowTemple() { | 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, {}, {}, { + 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)));}}), @@ -98,13 +98,13 @@ void AreaTable_Init_ShadowTemple() { 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)), }, {}); - 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), @@ -114,7 +114,7 @@ void AreaTable_Init_ShadowTemple() { 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))), //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) @@ -126,7 +126,7 @@ void AreaTable_Init_ShadowTemple() { //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), @@ -141,7 +141,7 @@ void AreaTable_Init_ShadowTemple() { 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);}}), }); - 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;}}), }, { @@ -156,7 +156,7 @@ 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))), @@ -166,7 +166,7 @@ void AreaTable_Init_ShadowTemple() { 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;}}), }); - 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)), @@ -180,7 +180,7 @@ 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; } }), @@ -189,7 +189,7 @@ void AreaTable_Init_ShadowTemple() { }); 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, { [] { 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..e6564474733 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,11 +4,11 @@ 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();}}), @@ -19,14 +19,14 @@ void AreaTable_Init_SpiritTemple() { | 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, {}, {}, { + 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;}}), }, { @@ -39,7 +39,7 @@ void AreaTable_Init_SpiritTemple() { 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))), @@ -52,7 +52,7 @@ void AreaTable_Init_SpiritTemple() { Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives || (randoCtx->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)), @@ -64,7 +64,7 @@ void AreaTable_Init_SpiritTemple() { 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) ))) || @@ -94,7 +94,7 @@ void AreaTable_Init_SpiritTemple() { 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), @@ -103,7 +103,7 @@ void AreaTable_Init_SpiritTemple() { 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), @@ -113,7 +113,7 @@ void AreaTable_Init_SpiritTemple() { 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)));}}), }); - 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))), @@ -123,7 +123,7 @@ void AreaTable_Init_SpiritTemple() { }); 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; } }), @@ -135,7 +135,7 @@ void AreaTable_Init_SpiritTemple() { | 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, {}, { + 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)))), @@ -147,7 +147,7 @@ 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);}}), }, { @@ -162,7 +162,7 @@ void AreaTable_Init_SpiritTemple() { 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))), @@ -181,7 +181,7 @@ void AreaTable_Init_SpiritTemple() { 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));}}), }); - 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)), @@ -197,7 +197,7 @@ void AreaTable_Init_SpiritTemple() { //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) @@ -208,7 +208,7 @@ void AreaTable_Init_SpiritTemple() { && 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)), }, { @@ -217,19 +217,19 @@ void AreaTable_Init_SpiritTemple() { }); 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; } }), }); - 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,7 +238,7 @@ 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 @@ -247,7 +247,7 @@ void AreaTable_Init_SpiritTemple() { 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..67c06b2dc69 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,11 +4,11 @@ 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();}}), @@ -20,7 +20,7 @@ void AreaTable_Init_WaterTemple() { ---------------------------*/ if (randoCtx->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))));}}), @@ -37,7 +37,7 @@ void AreaTable_Init_WaterTemple() { 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);}}), }, {}, { @@ -48,7 +48,7 @@ void AreaTable_Init_WaterTemple() { 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)), }, { @@ -56,7 +56,7 @@ void AreaTable_Init_WaterTemple() { 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);}}), }); - 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), }, { @@ -64,7 +64,7 @@ void AreaTable_Init_WaterTemple() { 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)), }, { @@ -72,13 +72,13 @@ void AreaTable_Init_WaterTemple() { 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);}}), }); - 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);}}), }); - 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));})), }, { @@ -88,26 +88,26 @@ void AreaTable_Init_WaterTemple() { 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));}}), }); - 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));}}), }); - 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);}}), }); - 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;}}), }, { @@ -118,7 +118,7 @@ void AreaTable_Init_WaterTemple() { 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);}}), }); - 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)))), }, { @@ -126,13 +126,13 @@ void AreaTable_Init_WaterTemple() { 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;}}), }); - 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));})), @@ -141,14 +141,14 @@ void AreaTable_Init_WaterTemple() { 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;}}), }); - 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);}}), }, { @@ -160,7 +160,7 @@ void AreaTable_Init_WaterTemple() { 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), }, { @@ -168,7 +168,7 @@ void AreaTable_Init_WaterTemple() { 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), }, { @@ -176,13 +176,13 @@ void AreaTable_Init_WaterTemple() { 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;}}), }); - 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,7 +190,7 @@ 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)), }, { @@ -198,7 +198,7 @@ void AreaTable_Init_WaterTemple() { 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))), }, { @@ -207,19 +207,19 @@ void AreaTable_Init_WaterTemple() { 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_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,7 +228,7 @@ 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))), @@ -237,7 +237,7 @@ void AreaTable_Init_WaterTemple() { 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;}}), }, {}, { @@ -251,7 +251,7 @@ void AreaTable_Init_WaterTemple() { | 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, {}, {}, { + 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);}}), @@ -259,7 +259,7 @@ void AreaTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->BossKeyWaterTemple && 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)))), @@ -269,7 +269,7 @@ void AreaTable_Init_WaterTemple() { 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)), @@ -278,7 +278,7 @@ void AreaTable_Init_WaterTemple() { 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;}}), @@ -291,7 +291,7 @@ void AreaTable_Init_WaterTemple() { 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))), @@ -304,7 +304,7 @@ 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; } }), @@ -312,7 +312,7 @@ void AreaTable_Init_WaterTemple() { 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..62a66dd9458 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,8 +3,8 @@ 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), }, { @@ -13,7 +13,7 @@ void AreaTable_Init_ZorasDomain() { 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->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}), @@ -46,13 +46,13 @@ void AreaTable_Init_ZorasDomain() { 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));}}), }); - 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), @@ -64,7 +64,7 @@ void AreaTable_Init_ZorasDomain() { 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,7 +72,7 @@ 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), @@ -82,7 +82,7 @@ void AreaTable_Init_ZorasDomain() { 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;}}), @@ -115,7 +115,7 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - 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), }, { @@ -124,7 +124,7 @@ void AreaTable_Init_ZorasDomain() { 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,7 +147,7 @@ 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->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), @@ -168,7 +168,7 @@ void AreaTable_Init_ZorasDomain() { 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 ef878f5131d..ab7b951e36a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -10,7 +10,7 @@ #include "randomizer.hpp" #include "spoiler_log.hpp" #include "location_access.hpp" -#include "../../debugger/performanceTimer.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include "../../randomizer/randomizerTypes.h" #include @@ -72,7 +72,7 @@ bool GenerateRandomizer(std::set excludedLocations, std::setReset time: {}ms", GetPerformanceTimer(PT_AREA_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()); diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index fc7d7d2e0fa..c3d73028c36 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -11,7 +11,7 @@ #include "variables.h" #include "soh/OTRGlobals.h" #include "../option.h" -#include "../../debugger/performanceTimer.h" +#include "soh/Enhancements/debugger/performanceTimer.h" namespace Playthrough { @@ -26,9 +26,9 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, ctx->ItemReset(); ctx->HintReset(); ctx->GetLogic()->Reset(); - StartPerformanceTimer(PT_AREA_RESET); - Areas::AccessReset(); - StopPerformanceTimer(PT_AREA_RESET); + 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 diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 170f93dccb0..9bd24b432fd 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; diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 8f1ea557f4c..b79bbcae1d9 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -395,498 +395,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 +422,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,121 +446,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 50800363c22..1e0ea1aae26 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -52,10 +52,6 @@ class Context { 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; void AddExcludedOptions(); void LocationReset(); void ClearItemLocations(); @@ -68,18 +64,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,29 +91,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; @@ -133,7 +100,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/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 8610734b9ce..9d32c5995f0 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -39,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_); } @@ -73,7 +73,7 @@ void Entrance::printAgeTimeAccess() { bool Entrance::ConditionsMet(bool allAgeTimes) const { auto ctx = Rando::Context::GetInstance(); StartPerformanceTimer(PT_ENTRANCE_LOGIC); - Area* parent = AreaTable(parentRegion); + Region* parent = RegionTable(parentRegion); int conditionsMet = 0; if (allAgeTimes && !parent->AllAccess()) { @@ -118,8 +118,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) { @@ -130,8 +130,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) { @@ -208,11 +208,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; @@ -224,10 +224,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; } @@ -254,7 +254,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) { @@ -265,7 +265,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(); @@ -276,7 +276,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); @@ -545,24 +545,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; } @@ -572,7 +572,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; } @@ -623,7 +623,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++; @@ -633,7 +633,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); @@ -885,7 +885,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/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 5fbab59a83c..f132754f3e5 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -39,14 +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(); } @@ -83,14 +83,14 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio if (giEntry != nullptr) { return giEntry; } - auto ctx = Rando::Context::GetInstance(); + auto logic = Rando::Context::GetInstance()->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); 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)) { actual = RG_DEKU_STICK_BAG; @@ -119,7 +119,7 @@ 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)) { actual = RG_DEKU_NUT_BAG; @@ -148,7 +148,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 +175,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 +202,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 +229,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 +242,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 +255,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 +271,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 +298,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 +315,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 +338,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/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index ba831183291..234d1e36497 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -7,8 +7,11 @@ #include #include +#include "soh/OTRGlobals.h" #include "dungeon.h" #include "context.h" +#include "macros.h" +#include "variables.h" #include namespace Rando { @@ -28,46 +31,46 @@ 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 && BuyBombchus) || 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; case RG_DISTANT_SCARECROW: @@ -82,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: @@ -120,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: @@ -146,7 +149,7 @@ 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_FOREST_TEMPLE_BOSS_KEY: case RG_FIRE_TEMPLE_BOSS_KEY: @@ -154,7 +157,7 @@ namespace Rando { 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: @@ -166,7 +169,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: @@ -178,23 +181,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: @@ -205,7 +208,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: @@ -409,7 +412,7 @@ namespace Rando { 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; + GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; } //Shouldn't be reached @@ -446,7 +449,7 @@ namespace Rando { return 0; } for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) { - uint8_t item = ctx->GetSaveContext()->inventory.items[i]; + uint8_t item = GetSaveContext()->inventory.items[i]; if (item != ITEM_NONE && (item != ITEM_LETTER_RUTO || (item == ITEM_LETTER_RUTO && DeliverLetter))) { count++; } @@ -468,7 +471,7 @@ namespace Rando { BuyArrow = GetInLogic(LOGIC_BUY_ARROW); BuyBomb = GetInLogic(LOGIC_BUY_BOMB); BuyMagicPotion = GetInLogic(LOGIC_BUY_MAGIC_POTION); - MagicBean = ctx->GetAmmo(ITEM_BEAN) > 0; + MagicBean = GetAmmo(ITEM_BEAN) > 0; RutosLetter = CanUse(RG_RUTOS_LETTER); Boomerang = CanUse(RG_BOOMERANG); DinsFire = CanUse(RG_DINS_FIRE); @@ -504,7 +507,7 @@ namespace Rando { 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; + BombchusEnabled = ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) ? CheckInventory(ITEM_BOMBCHU, true) : BombBag; BuyBombchus = (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant); Hookshot = CanUse(RG_HOOKSHOT); Longshot = CanUse(RG_LONGSHOT); @@ -519,8 +522,8 @@ namespace Rando { 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); + ProgressiveScale = CurrentUpgrade(UPG_SCALE) + HasItem(RG_BRONZE_SCALE); + ProgressiveWallet = CurrentUpgrade(UPG_WALLET) + HasItem(RG_CHILD_WALLET); CanSummonGohma = HasBossSoul(RG_GOHMA_SOUL); CanSummonKingDodongo = HasBossSoul(RG_KING_DODONGO_SOUL); @@ -551,9 +554,9 @@ namespace Rando { LightMedallion = HasItem(RG_LIGHT_MEDALLION); DoubleDefense = HasItem(RG_DOUBLE_DEFENSE); - TriforcePieces = ctx->GetSaveContext()->triforcePiecesCollected; + TriforcePieces = GetSaveContext()->triforcePiecesCollected; Greg = HasItem(RG_GREG_RUPEE); - GoldSkulltulaTokens = ctx->GetGSCount(); + GoldSkulltulaTokens = GetGSCount(); //you need at least 2 buttons for scarecrow song ScarecrowSong = ScarecrowSong || (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && Ocarina && OcarinaButtons >= 2) || (ChildScarecrow && AdultScarecrow); @@ -598,7 +601,7 @@ namespace Rando { 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; + Hearts = 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; @@ -678,58 +681,58 @@ 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; @@ -765,6 +768,777 @@ namespace Rando { return false; } + 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)); + } + 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; + } + UpdateHelpers(); + } + + 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) { ctx = _ctx; } @@ -778,7 +1552,7 @@ namespace Rando { } void Logic::Reset() { - ctx->NewSaveContext(); + NewSaveContext(); StartPerformanceTimer(PT_LOGIC_RESET); memset(inLogic, false, sizeof(inLogic)); //Settings-dependent variables @@ -879,15 +1653,15 @@ namespace Rando { //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); + 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); ProgressiveBulletBag = 0; ProgressiveBombBag = 0; ProgressiveMagic = 0; @@ -895,7 +1669,7 @@ namespace Rando { ProgressiveScale = 0; 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; @@ -903,7 +1677,7 @@ namespace Rando { ProgressiveWallet = 0; if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { ProgressiveWallet = 1; - ctx->SetRandoInf(RAND_INF_HAS_WALLET, true); + SetRandoInf(RAND_INF_HAS_WALLET, true); } ProgressiveStrength = 0; ProgressiveOcarina = 0; @@ -911,7 +1685,7 @@ namespace Rando { //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 @@ -1077,7 +1851,7 @@ namespace Rando { AtDay = false; AtNight = false; Age = ctx->GetSettings()->ResolvedStartingAge(); - ctx->GetSaveContext()->linkAge = !Age; + GetSaveContext()->linkAge = !Age; //Events ShowedMidoSwordAndShield = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index d5de5f89942..89cb25927f0 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -387,7 +387,7 @@ class Logic { bool BuyDekuShieldPast = false; bool TimeTravelPast = false; - SaveContext* mSaveContext; + SaveContext* mSaveContext = nullptr; Logic(); void UpdateHelpers(); bool CanUse(RandomizerGet itemName); @@ -406,6 +406,37 @@ class Logic { 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/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index fa67fd1eb18..9a19acde330 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -887,7 +887,7 @@ void CheckTrackerWindow::DrawElement() { return; } - AreaTable_Init(); + RegionTable_Init(); ImGui::TableNextRow(0, headerHeight); ImGui::TableNextColumn(); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 10e3a694b40..faded27e306 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -2843,7 +2843,7 @@ extern "C" void Save_LoadFile(void) { // Reset rando context for rando saves. OTRGlobals::Instance->gRandoContext.reset(); OTRGlobals::Instance->gRandoContext = Rando::Context::CreateInstance(); - OTRGlobals::Instance->gRandoContext->SetSaveContext(&gSaveContext); + OTRGlobals::Instance->gRandoContext->GetLogic()->SetSaveContext(&gSaveContext); OTRGlobals::Instance->gRandoContext->AddExcludedOptions(); OTRGlobals::Instance->gRandoContext->GetSettings()->CreateOptions(); } From 5d62f5690a8de0b69a784b894e5fd41f16d2963b Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:42:25 +0100 Subject: [PATCH 25/43] remove an unused region --- .../locacc_dodongos_cavern.cpp | 34 +++++++++---------- .../Enhancements/randomizer/randomizerTypes.h | 1 - 2 files changed, 17 insertions(+), 18 deletions(-) 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 0a30f19a8ac..150be19fe2b 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 @@ -229,7 +229,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER] = Area("Dodongos Cavern MQ Stairs Upper", "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), }, { @@ -238,7 +238,7 @@ void RegionTable_Init_DodongosCavern() { 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_STAIRS_PAST_BIG_SKULLTULAS] = Area("Dodongos Cavern MQ Past Big Skulltulas", "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->CanTakeDamage;}}), @@ -248,7 +248,7 @@ void RegionTable_Init_DodongosCavern() { 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] = Area("Dodongos Cavern MQ Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + 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, logic->CanKillEnemy(RE_DODONGO) || logic->CanUse(RG_GORONS_BRACELET)), }, { @@ -257,7 +257,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO) || logic->CanUse(RG_GORONS_BRACELET);});}}), }); - 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_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*/) && randoCtx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}}), }, {}, { @@ -270,13 +270,13 @@ void RegionTable_Init_DodongosCavern() { 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] = Area("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + 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), //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 @@ -285,7 +285,7 @@ void RegionTable_Init_DodongosCavern() { 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_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->CanBlastOrSmash), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA) }, { @@ -295,13 +295,13 @@ void RegionTable_Init_DodongosCavern() { 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_TWO_FIRES_ROOM] = Area("Dodongos Cavern MQ Before Upper Lizalfos", "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->CanBlastOrSmash || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}));}}), }); - 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_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);}}), }, { @@ -322,7 +322,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->CanDetonateBombFlowers() || logic->CanUse(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 }, {}, { @@ -331,7 +331,7 @@ void RegionTable_Init_DodongosCavern() { 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] = Area("Dodongos Cavern MQ Poes Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + 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->CanUse(RG_GORONS_BRACELET);}) && //could be a seperate room if it gets busy @@ -344,7 +344,7 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->CanUse(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM] = Area("Dodongos Cavern Mad Scrub 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_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))) @@ -353,7 +353,7 @@ void RegionTable_Init_DodongosCavern() { 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] = Area("Dodongos Cavern MQ Behind Mouth", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + 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: @@ -362,18 +362,18 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, {[]{return logic->IsAdult;}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Area("Dodongos Cavern MQ Back Behind Fire", "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), //pulling the grave isn't required, as you can open the chest through it }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return logic->CanAttack();}}), //There's a trick N64 rolls into the child eyes trick for using armos blow up the bomb flowers when dieing, which would be killing an armos - Entrance(RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, []{return logic->CanDetonateBombFlowers();}) || + 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_BOSS_AREA] = Area("Dodongos Cavern MQ BossArea", "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;}}), }, { @@ -397,7 +397,7 @@ void RegionTable_Init_DodongosCavern() { { // 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_MQ_BEHIND_MOUTH, { [] { return randoCtx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }), Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }), }); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index ec6171348f6..94917fb5f8b 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -556,7 +556,6 @@ typedef enum { RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, - RR_DODONGOS_CAVERN_MQ_BEFORE_BOSS, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, From 4e4c1c4f8aab5d486ce622b1c990f4d5fd9caa92 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 24 Sep 2024 12:56:56 -0500 Subject: [PATCH 26/43] Handle ignoring 0x3F for navi talk skips (#4364) --- soh/soh/Enhancements/timesaver_hook_handlers.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 0682f4de13d..77910d68714 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -317,9 +317,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* case VB_NAVI_TALK: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.NoForcedDialog"), IS_RANDO)) { ElfMsg* naviTalk = static_cast(opt); - Flags_SetSwitch(gPlayState, (naviTalk->actor.params >> 8) & 0x3F); - Actor_Kill(&naviTalk->actor); - *should = false; + if (((naviTalk->actor.params >> 8) & 0x3F) != 0x3F) { + Flags_SetSwitch(gPlayState, (naviTalk->actor.params >> 8) & 0x3F); + Actor_Kill(&naviTalk->actor); + *should = false; + } } break; } From 7810f7505a2294d5746d2d368a3352e6ef1308ed Mon Sep 17 00:00:00 2001 From: skrawpie <21212370+skrawpie@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:57:16 -0400 Subject: [PATCH 27/43] Update settings.cpp (#4362) 100 GS Reward was missing from RSK_GANONS_BOSS_KEY causing indexing issues. Notably, Triforce Hunt was setting Ganon's Boss Key to "Vanilla" rather than "Triforce Hunt." --- soh/soh/Enhancements/randomizer/settings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index f3f860800bc..fd24a77f83a 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -129,7 +129,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); @@ -2770,4 +2770,4 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { GetTrickOption(rt).SetSelectedIndex(RO_GENERIC_ON); } } -} // namespace Rando \ No newline at end of file +} // namespace Rando From b3b9216b5c01f37bcd8563beb9ca7f637acd880d Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 25 Sep 2024 14:01:59 -0500 Subject: [PATCH 28/43] Show interface after item get (when skipping GI) (#4363) --- soh/soh/Enhancements/randomizer/hook_handlers.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 55275844336..eb7d30b8791 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -790,6 +790,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) { From da5cf114499f7acff78b69c5d69e2084074bfa69 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:26:12 +0200 Subject: [PATCH 29/43] Hook Debugger (#4323) * Initial implementation * Add call number & relax source_location requirement * Update hookDebugger.cpp --- .../Enhancements/debugger/hookDebugger.cpp | 111 ++++++++++++ soh/soh/Enhancements/debugger/hookDebugger.h | 10 ++ .../game-interactor/GameInteractor.h | 168 +++++++++++------- .../GameInteractor_HookTable.h | 57 ++++++ soh/soh/SohGui.cpp | 4 + soh/soh/SohGui.hpp | 1 + soh/soh/SohMenuBar.cpp | 8 + 7 files changed, 296 insertions(+), 63 deletions(-) create mode 100644 soh/soh/Enhancements/debugger/hookDebugger.cpp create mode 100644 soh/soh/Enhancements/debugger/hookDebugger.h create mode 100644 soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h 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/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index ce5a18b6ed6..f97fe9f2612 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -458,6 +458,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 @@ -466,11 +472,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) @@ -479,7 +514,7 @@ class GameInteractor { public: static GameInteractor* Instance; - // Gsme State + // Game State class State { public: static bool NoUIActive; @@ -532,7 +567,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; @@ -540,50 +579,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; } @@ -591,29 +654,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; } @@ -621,31 +694,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; } } } @@ -672,59 +756,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); @@ -785,5 +825,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/SohGui.cpp b/soh/soh/SohGui.cpp index 4bef8cea675..eda8641ef0b 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -122,6 +122,7 @@ namespace SohGui { std::shared_ptr mActorViewerWindow; std::shared_ptr mColViewerWindow; std::shared_ptr mSaveEditorWindow; + std::shared_ptr mHookDebuggerWindow; std::shared_ptr mDLViewerWindow; std::shared_ptr mValueViewerWindow; std::shared_ptr mMessageViewerWindow; @@ -179,6 +180,8 @@ namespace SohGui { gui->AddGuiWindow(mColViewerWindow); mSaveEditorWindow = std::make_shared(CVAR_WINDOW("SaveEditor"), "Save Editor", ImVec2(520, 600)); gui->AddGuiWindow(mSaveEditorWindow); + mHookDebuggerWindow = std::make_shared(CVAR_WINDOW("HookDebugger"), "Hook Debugger", ImVec2(1250, 850)); + gui->AddGuiWindow(mHookDebuggerWindow); mDLViewerWindow = std::make_shared(CVAR_WINDOW("DLViewer"), "Display List Viewer", ImVec2(520, 600)); gui->AddGuiWindow(mDLViewerWindow); mValueViewerWindow = std::make_shared(CVAR_WINDOW("ValueViewer"), "Value Viewer", ImVec2(520, 600)); @@ -226,6 +229,7 @@ namespace SohGui { mValueViewerWindow = nullptr; mMessageViewerWindow = nullptr; mSaveEditorWindow = nullptr; + mHookDebuggerWindow = nullptr; mColViewerWindow = nullptr; mActorViewerWindow = nullptr; mCosmeticsEditorWindow = nullptr; diff --git a/soh/soh/SohGui.hpp b/soh/soh/SohGui.hpp index 5152bf69c53..9bdedc50464 100644 --- a/soh/soh/SohGui.hpp +++ b/soh/soh/SohGui.hpp @@ -16,6 +16,7 @@ #include "Enhancements/debugger/actorViewer.h" #include "Enhancements/debugger/colViewer.h" #include "Enhancements/debugger/debugSaveEditor.h" +#include "Enhancements/debugger/hookDebugger.h" #include "Enhancements/debugger/dlViewer.h" #include "Enhancements/debugger/valueViewer.h" #include "Enhancements/gameplaystatswindow.h" diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 35f0b6ae141..31ef681fc05 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -28,6 +28,7 @@ #include "Enhancements/debugger/actorViewer.h" #include "Enhancements/debugger/colViewer.h" #include "Enhancements/debugger/debugSaveEditor.h" +#include "Enhancements/debugger/hookDebugger.h" #include "Enhancements/debugger/dlViewer.h" #include "Enhancements/debugger/valueViewer.h" #include "Enhancements/gameplaystatswindow.h" @@ -1761,6 +1762,7 @@ void DrawCheatsMenu() { extern std::shared_ptr mStatsWindow; extern std::shared_ptr mConsoleWindow; extern std::shared_ptr mSaveEditorWindow; +extern std::shared_ptr mHookDebuggerWindow; extern std::shared_ptr mColViewerWindow; extern std::shared_ptr mActorViewerWindow; extern std::shared_ptr mDLViewerWindow; @@ -1844,6 +1846,12 @@ void DrawDeveloperToolsMenu() { } } UIWidgets::Spacer(0); + if (mHookDebuggerWindow) { + if (ImGui::Button(GetWindowButtonText("Hook Debugger", CVarGetInteger(CVAR_WINDOW("HookDebugger"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) { + mHookDebuggerWindow->ToggleVisibility(); + } + } + UIWidgets::Spacer(0); if (mColViewerWindow) { if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVarGetInteger(CVAR_WINDOW("CollisionViewer"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) { mColViewerWindow->ToggleVisibility(); From 159d0872d71c095f36e90629ecfb43880a77a753 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 27 Sep 2024 00:26:33 +0100 Subject: [PATCH 30/43] remove unused functions (#4313) --- .../Enhancements/randomizer/randomizer.cpp | 518 +----------------- soh/soh/Enhancements/randomizer/randomizer.h | 3 - 2 files changed, 2 insertions(+), 519 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 01ff89d2d68..92b8f3e2f0f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -146,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; } } @@ -729,520 +729,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 = { @@ -2525,7 +2011,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", diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 9942fa564e3..14f28311cd3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -25,7 +25,6 @@ class Randomizer { private: std::unordered_map randoSettings; - bool IsItemVanilla(RandomizerGet randoGet); public: Randomizer(); @@ -56,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); @@ -69,7 +67,6 @@ class Randomizer { static CustomMessage GetRupeeMessage(u16 rupeeTextId); static CustomMessage GetIceTrapMessage(); static CustomMessage GetTriforcePieceMessage(); - bool CheckContainsVanillaItem(RandomizerCheck randoCheck); }; #ifdef __cplusplus From 0f47e6394e5e9f9db91ca2a6489dbe8566fed2d2 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:35:20 +0100 Subject: [PATCH 31/43] fix small hint issues (#4358) --- soh/soh/Enhancements/randomizer/3drando/hints.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 9b22706cdc0..aca52307214 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -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)); } From 668f0fe4c612675f0616ac329197196b7974c8ef Mon Sep 17 00:00:00 2001 From: Malkierian Date: Fri, 27 Sep 2024 22:47:35 -0700 Subject: [PATCH 32/43] Rando V3 - Small UI Cleanup (#4367) * Change tristate off graphic to none instead of X to avoid confusion. Modify Combobox and Slider Options to clamp directly to options.size() - 1 instead of just decrementing if current value is higher than max. * Restore RenderCross line, but commented out. --- soh/soh/Enhancements/randomizer/option.cpp | 5 +++-- soh/soh/UIWidgets.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) 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/UIWidgets.cpp b/soh/soh/UIWidgets.cpp index c47ae91f73f..5a41fe7cd89 100644 --- a/soh/soh/UIWidgets.cpp +++ b/soh/soh/UIWidgets.cpp @@ -170,7 +170,7 @@ namespace UIWidgets { ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); } else if ((!disabled && !*v && renderCrossWhenOff) || (disabled && disabledGraphic == CheckboxGraphics::Cross)) { const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); - RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), disabled ? cross_col : check_col, square_sz - pad * 2.0f); + //RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), disabled ? cross_col : check_col, square_sz - pad * 2.0f); // Caused confusion as to status } ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); From 0cfd535fe6f63a526d104382ed512d76149b1898 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:50:47 +0200 Subject: [PATCH 33/43] Clean up location table (#4258) * Remove categories * Remove SpoilerCollectionCheckGroup * Remove unused Location constructors * Remove LocationType * Remove unused SpoilerCollectionCheckTypes * Remove hints' isVanillaCompletion, it's always false * Remove SpoilerCollectionCheck::None Same effect as default constructor * Fix mistake * Update location.h * Deduce RC Area by scene when possible * Remove useless constructors * Remove flag in most situations * Format improvements * Replace overworldLocations with a function * Replace shopLocationLists with a function * Replace gossipStoneLocations with a function Also add a new RCType for static hints * Replace scrubLocations with a function * Replace staticHintLocations with a function * Replace overworldFishLocations with a function * Replace pondFishLocations with a function * Remove RC_TRIFORCE_COMPLETED from GetOverworldLocations * Update fill.cpp Re-add filter for dungeonLocations for song shuffle dungeon rewards (and fix erroneous check for song locations there). Modify songLocations filter for dungeon rewards to check for RCTYPE_BOSS_HEART_OR_OTHER_REWARD and then the two song locations added for it. * Update fill.cpp Fix bracketing. * Apply Pepper0ni's patch --------- Co-authored-by: Malkierian --- .../randomizer/3drando/category.hpp | 21 - .../Enhancements/randomizer/3drando/fill.cpp | 62 +- .../Enhancements/randomizer/3drando/hints.cpp | 10 +- .../randomizer/3drando/item_pool.cpp | 10 +- .../randomizer/3drando/location_access.cpp | 2 +- .../Enhancements/randomizer/3drando/shops.cpp | 10 +- .../randomizer/3drando/spoiler_log.cpp | 65 +- .../randomizer/3drando/spoiler_log.hpp | 43 +- soh/soh/Enhancements/randomizer/context.cpp | 28 +- soh/soh/Enhancements/randomizer/context.h | 3 +- soh/soh/Enhancements/randomizer/dungeon.cpp | 8 +- .../Enhancements/randomizer/fishsanity.cpp | 12 +- .../Enhancements/randomizer/item_location.cpp | 4 +- soh/soh/Enhancements/randomizer/location.cpp | 600 ++--- soh/soh/Enhancements/randomizer/location.h | 357 +-- .../Enhancements/randomizer/location_list.cpp | 2327 +++++++---------- .../Enhancements/randomizer/randomizerTypes.h | 22 +- .../randomizer/randomizer_check_objects.cpp | 6 +- .../randomizer/randomizer_check_tracker.cpp | 9 +- soh/soh/Enhancements/randomizer/settings.cpp | 76 +- soh/soh/Enhancements/randomizer/settings.h | 6 +- soh/soh/Enhancements/randomizer/static_data.h | 14 +- 22 files changed, 1450 insertions(+), 2245 deletions(-) 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 2a6f3ed088c..953b9338a87 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -977,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; }); @@ -1022,7 +1024,7 @@ static void RandomizeDungeonItems() { //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 + //Rando::StaticData::GetOverworldLocations() defined in item_location.cpp //Create Any Dungeon and Overworld item pools std::vector anyDungeonItems; @@ -1074,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()) { @@ -1083,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); } } } @@ -1192,17 +1194,19 @@ int Fill() { //Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. const std::array indices = {7, 5, 8, 6}; //Overwrite appropriate number of shop items - for (size_t i = 0; i < Rando::StaticData::shopLocationLists.size(); i++) { + #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-4 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 = + NonShopItems[TransformShopIndex(i * LOCATIONS_PER_SHOP + itemindex - 1)].Price = shopsanityPrice; // Set price to be retrieved by the patch and textboxes - ctx->GetItemLocation(Rando::StaticData::shopLocationLists[i][itemindex - 1])->SetCustomPrice(shopsanityPrice); + ctx->GetItemLocation(Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1])->SetCustomPrice(shopsanityPrice); } } + #undef LOCATIONS_PER_SHOP } //Get all locations and items that don't have a shopsanity price attached std::vector shopLocations = {}; @@ -1210,12 +1214,9 @@ 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 @@ -1246,11 +1247,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; }); } @@ -1282,26 +1285,25 @@ int Fill() { 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()); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index aca52307214..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 = ReachabilitySearch(Rando::StaticData::gossipStoneLocations); + auto accessibleGossipStones = ReachabilitySearch(Rando::StaticData::GetGossipStoneLocations()); //Give the item back to the location ctx->GetItemLocation(hintedLocation)->SetPlacedItem(originalItem); @@ -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); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index f7250e17ddf..33e6df5d445 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 { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 33ef7ccbd36..6fc4c04c9ba 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -47,7 +47,7 @@ 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; } diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 6f785b505c1..1aeb3379b6a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -15,13 +15,11 @@ bool initTrickNames = false; //Indicates if trick ice trap names have been initi //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 diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 9bd24b432fd..10301d29749 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -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,7 +159,7 @@ void WriteIngameSpoilerLog() { } // PURPLE TODO: LOCALIZATION auto locItem = itemLocation->GetPlacedItemName().GetEnglish(); - if (itemLocation->GetPlacedRandomizerGet() == RG_ICE_TRAP && loc->IsCategory(Category::cShop)) { + if (itemLocation->GetPlacedRandomizerGet() == RG_ICE_TRAP && loc->GetRCType() == RCTYPE_SHOP) { locItem = NonShopItems[TransformShopIndex(GetShopIndex(key))].Name.GetEnglish(); } if (stringOffsetMap.find(locItem) == stringOffsetMap.end()) { @@ -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); 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 b79bbcae1d9..09a6b40d504 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -105,7 +105,7 @@ 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)) { + StaticData::GetLocation(locKey)->GetRCType() == RCTYPE_SHOP) { const int index = TransformShopIndex(GetShopIndex(locKey)); NonShopItems[index].Name = StaticData::RetrieveItem(item).GetName(); NonShopItems[index].Repurchaseable = @@ -136,11 +136,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 +152,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 +161,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() { @@ -198,17 +196,17 @@ void Context::LocationReset() { GetItemLocation(il)->RemoveFromPool(); } - for (const RandomizerCheck il : StaticData::gossipStoneLocations) { + for (const RandomizerCheck il : StaticData::GetGossipStoneLocations()) { GetItemLocation(il)->RemoveFromPool(); } - for (const RandomizerCheck il : StaticData::staticHintLocations) { + for (const RandomizerCheck il : StaticData::GetStaticHintLocations()) { GetItemLocation(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,7 +225,7 @@ 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)) { + if (loc->GetRCType() == RCTYPE_SHOP) { NonShopItems[TransformShopIndex(GetShopIndex(locKey))].Name = val.GetTrickName(); } overrides[locKey] = val; diff --git a/soh/soh/Enhancements/randomizer/context.h b/soh/soh/Enhancements/randomizer/context.h index 1e0ea1aae26..a1a7d0d5451 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -50,8 +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::vector GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType); void AddExcludedOptions(); void LocationReset(); void ClearItemLocations(); 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/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index 52789f17ed1..5c0eda47507 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -87,10 +87,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 +138,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 +299,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 diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index d303b3c3b17..1ff41c41123 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -174,13 +174,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); } } diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index ddc9f7fc208..9dfceb5ab91 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,277 @@ 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_}; + 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::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 }; } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index bd7f69a8bbc..39338040235 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,45 @@ 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 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..4089e1deb79 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -6,1377 +6,862 @@ 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, - - RC_LLR_GS_BACK_WALL, - RC_LLR_GS_RAIN_SHED, - RC_LLR_GS_HOUSE_WINDOW, - RC_LLR_GS_TREE, +using namespace Rando; - 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::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; +} -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::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::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::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::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::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::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::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; +} -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::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; +} -using namespace Rando; +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 + ) { + 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 +870,191 @@ 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::Base(RC_LH_CHILD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 100, "Child Pond Fish 1", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_2] = Location::Base(RC_LH_CHILD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 101, "Child Pond Fish 2", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_3] = Location::Base(RC_LH_CHILD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 102, "Child Pond Fish 3", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_4] = Location::Base(RC_LH_CHILD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 103, "Child Pond Fish 4", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_5] = Location::Base(RC_LH_CHILD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 104, "Child Pond Fish 5", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_6] = Location::Base(RC_LH_CHILD_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 105, "Child Pond Fish 6", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_7] = Location::Base(RC_LH_CHILD_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 106, "Child Pond Fish 7", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_8] = Location::Base(RC_LH_CHILD_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 107, "Child Pond Fish 8", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_9] = Location::Base(RC_LH_CHILD_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 108, "Child Pond Fish 9", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_10] = Location::Base(RC_LH_CHILD_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 109, "Child Pond Fish 10", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_11] = Location::Base(RC_LH_CHILD_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 110, "Child Pond Fish 11", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_12] = Location::Base(RC_LH_CHILD_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 111, "Child Pond Fish 12", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_13] = Location::Base(RC_LH_CHILD_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 112, "Child Pond Fish 13", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_14] = Location::Base(RC_LH_CHILD_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 113, "Child Pond Fish 14", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_FISH_15] = Location::Base(RC_LH_CHILD_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 114, "Child Pond Fish 15", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_CHILD_LOACH_1] = Location::Base(RC_LH_CHILD_LOACH_1, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 115, "Child Pond Loach 1", RHT_LH_HYRULE_LOACH, RG_NONE); + locationTable[RC_LH_CHILD_LOACH_2] = Location::Base(RC_LH_CHILD_LOACH_2, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 116, "Child Pond Loach 2", RHT_LH_HYRULE_LOACH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_1] = Location::Base(RC_LH_ADULT_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 100, "Adult Pond Fish 1", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_2] = Location::Base(RC_LH_ADULT_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 101, "Adult Pond Fish 2", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_3] = Location::Base(RC_LH_ADULT_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 102, "Adult Pond Fish 3", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_4] = Location::Base(RC_LH_ADULT_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 103, "Adult Pond Fish 4", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_5] = Location::Base(RC_LH_ADULT_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 104, "Adult Pond Fish 5", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_6] = Location::Base(RC_LH_ADULT_FISH_6, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 105, "Adult Pond Fish 6", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_7] = Location::Base(RC_LH_ADULT_FISH_7, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 106, "Adult Pond Fish 7", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_8] = Location::Base(RC_LH_ADULT_FISH_8, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 107, "Adult Pond Fish 8", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_9] = Location::Base(RC_LH_ADULT_FISH_9, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 108, "Adult Pond Fish 9", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_10] = Location::Base(RC_LH_ADULT_FISH_10, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 109, "Adult Pond Fish 10", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_11] = Location::Base(RC_LH_ADULT_FISH_11, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 110, "Adult Pond Fish 11", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_12] = Location::Base(RC_LH_ADULT_FISH_12, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 111, "Adult Pond Fish 12", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_13] = Location::Base(RC_LH_ADULT_FISH_13, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 112, "Adult Pond Fish 13", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_14] = Location::Base(RC_LH_ADULT_FISH_14, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 113, "Adult Pond Fish 14", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_FISH_15] = Location::Base(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 114, "Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE); + locationTable[RC_LH_ADULT_LOACH] = Location::Base(RC_LH_ADULT_LOACH, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_FISHING, SCENE_FISHING_POND, 115, "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::Base(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCTYPE_FISH, RCAREA_KOKIRI_FOREST, ACTOR_EN_FISH, SCENE_GROTTOS, 1, "Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH, RG_FISH); + 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, "Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH, RG_FISH); + 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, "Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH, RG_FISH); + 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, "Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH, RG_FISH); + 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, "Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH, RG_FISH); + 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, "Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH, RG_FISH); + 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, "Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH, RG_FISH); + 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, "Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH, RG_FISH); + 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, "Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH, RG_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::Base(RC_ZD_FISH_1, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, "Fish 1", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_2] = Location::Base(RC_ZD_FISH_2, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, "Fish 2", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_3] = Location::Base(RC_ZD_FISH_3, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 2, "Fish 3", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_4] = Location::Base(RC_ZD_FISH_4, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, "Fish 4", RHT_ZD_FISH, RG_FISH); + locationTable[RC_ZD_FISH_5] = Location::Base(RC_ZD_FISH_5, RCQUEST_BOTH, RCTYPE_FISH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, "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/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 304fef213cd..28cd8dee1f4 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -247,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; @@ -3651,17 +3653,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, @@ -3669,9 +3675,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, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 3b5eed450f7..4614a24d1be 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -143,8 +143,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 +169,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 9a19acde330..33fe121daf8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -734,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; @@ -1225,6 +1221,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) && @@ -1262,7 +1259,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) && diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index fd24a77f83a..5bbd66d5839 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() { @@ -217,7 +217,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."); @@ -1007,44 +1007,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 +1064,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", { @@ -1267,12 +1283,12 @@ const std::array& Settings::GetAllOptions() const { return mOptions; } -std::vector